Browse Source

Support @Validated at method level for overriding validation groups

Issue: SPR-9174
pull/701/head
Juergen Hoeller 10 years ago
parent
commit
5e3edc667e
  1. 10
      spring-context/src/main/java/org/springframework/validation/annotation/Validated.java
  2. 7
      spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationInterceptor.java
  3. 13
      spring-context/src/test/java/org/springframework/validation/beanvalidation/MethodValidationTests.java

10
spring-context/src/main/java/org/springframework/validation/annotation/Validated.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 the original author or authors.
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -35,7 +35,11 @@ import java.lang.annotation.Target; @@ -35,7 +35,11 @@ import java.lang.annotation.Target;
* class is supposed to be validated at the method level (acting as a pointcut
* for the corresponding validation interceptor), but also optionally specifying
* the validation groups for method-level validation in the annotated class.
* Can also be used as a meta-annotation on a custom stereotype annotation.
* Applying this annotation at the method level allows for overriding the
* validation groups for a specific method but does not serve as a pointcut;
* a class-level annotation is nevertheless necessary to trigger method validation
* for a specific bean to begin with. Can also be used as a meta-annotation on a
* custom stereotype annotation or a custom group-specific validated annotation.
*
* @author Juergen Hoeller
* @since 3.1
@ -44,7 +48,7 @@ import java.lang.annotation.Target; @@ -44,7 +48,7 @@ import java.lang.annotation.Target;
* @see org.springframework.validation.beanvalidation.SpringValidatorAdapter
* @see org.springframework.validation.beanvalidation.MethodValidationPostProcessor
*/
@Target({ElementType.TYPE, ElementType.PARAMETER})
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Validated {

7
spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationInterceptor.java

@ -141,8 +141,11 @@ public class MethodValidationInterceptor implements MethodInterceptor { @@ -141,8 +141,11 @@ public class MethodValidationInterceptor implements MethodInterceptor {
* @return the applicable validation groups as a Class array
*/
protected Class<?>[] determineValidationGroups(MethodInvocation invocation) {
Validated valid = AnnotationUtils.findAnnotation(invocation.getThis().getClass(), Validated.class);
return (valid != null ? valid.value() : new Class<?>[0]);
Validated validatedAnn = AnnotationUtils.findAnnotation(invocation.getMethod(), Validated.class);
if (validatedAnn == null) {
validatedAnn = AnnotationUtils.findAnnotation(invocation.getThis().getClass(), Validated.class);
}
return (validatedAnn != null ? validatedAnn.value() : new Class<?>[0]);
}

13
spring-context/src/test/java/org/springframework/validation/beanvalidation/MethodValidationTests.java

@ -124,7 +124,8 @@ public class MethodValidationTests { @@ -124,7 +124,8 @@ public class MethodValidationTests {
@NotNull Object myValidMethod(@NotNull(groups = MyGroup.class) String arg1, @Max(10) int arg2);
@Async void myValidAsyncMethod(@NotNull(groups = MyGroup.class) String arg1, @Max(10) int arg2);
@MyValid
@Async void myValidAsyncMethod(@NotNull(groups = OtherGroup.class) String arg1, @Max(10) int arg2);
}
@ -132,9 +133,19 @@ public class MethodValidationTests { @@ -132,9 +133,19 @@ public class MethodValidationTests {
}
public interface OtherGroup {
}
@Validated({MyGroup.class, Default.class})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyStereotype {
}
@Validated({OtherGroup.class, Default.class})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyValid {
}
}

Loading…
Cancel
Save