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 @@
/* /*
* 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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -35,7 +35,11 @@ import java.lang.annotation.Target;
* class is supposed to be validated at the method level (acting as a pointcut * class is supposed to be validated at the method level (acting as a pointcut
* for the corresponding validation interceptor), but also optionally specifying * for the corresponding validation interceptor), but also optionally specifying
* the validation groups for method-level validation in the annotated class. * 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 * @author Juergen Hoeller
* @since 3.1 * @since 3.1
@ -44,7 +48,7 @@ import java.lang.annotation.Target;
* @see org.springframework.validation.beanvalidation.SpringValidatorAdapter * @see org.springframework.validation.beanvalidation.SpringValidatorAdapter
* @see org.springframework.validation.beanvalidation.MethodValidationPostProcessor * @see org.springframework.validation.beanvalidation.MethodValidationPostProcessor
*/ */
@Target({ElementType.TYPE, ElementType.PARAMETER}) @Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Documented @Documented
public @interface Validated { public @interface Validated {

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

@ -141,8 +141,11 @@ public class MethodValidationInterceptor implements MethodInterceptor {
* @return the applicable validation groups as a Class array * @return the applicable validation groups as a Class array
*/ */
protected Class<?>[] determineValidationGroups(MethodInvocation invocation) { protected Class<?>[] determineValidationGroups(MethodInvocation invocation) {
Validated valid = AnnotationUtils.findAnnotation(invocation.getThis().getClass(), Validated.class); Validated validatedAnn = AnnotationUtils.findAnnotation(invocation.getMethod(), Validated.class);
return (valid != null ? valid.value() : new Class<?>[0]); 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 {
@NotNull Object myValidMethod(@NotNull(groups = MyGroup.class) String arg1, @Max(10) int arg2); @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 {
} }
public interface OtherGroup {
}
@Validated({MyGroup.class, Default.class}) @Validated({MyGroup.class, Default.class})
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface MyStereotype { public @interface MyStereotype {
} }
@Validated({OtherGroup.class, Default.class})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyValid {
}
} }

Loading…
Cancel
Save