Skip to content

Commit 8330134

Browse files
committed
Unwrap SpringValidatorAdapter (e.g. CustomValidatorBean) to native Validator
Issue: SPR-15629
1 parent 9cb9884 commit 8330134

File tree

2 files changed

+24
-3
lines changed

2 files changed

+24
-3
lines changed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,13 @@ public void setValidatedAnnotationType(Class<? extends Annotation> validatedAnno
8585
* <p>Default is the default ValidatorFactory's default Validator.
8686
*/
8787
public void setValidator(Validator validator) {
88+
// Unwrap to the native Validator with forExecutables support
8889
if (validator instanceof LocalValidatorFactoryBean) {
8990
this.validator = ((LocalValidatorFactoryBean) validator).getValidator();
9091
}
92+
else if (validator instanceof SpringValidatorAdapter) {
93+
this.validator = validator.unwrap(Validator.class);
94+
}
9195
else {
9296
this.validator = validator;
9397
}

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

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
import java.util.Set;
2626
import java.util.TreeMap;
2727
import javax.validation.ConstraintViolation;
28+
import javax.validation.ValidationException;
29+
import javax.validation.Validator;
2830
import javax.validation.metadata.BeanDescriptor;
2931
import javax.validation.metadata.ConstraintDescriptor;
3032

@@ -39,13 +41,19 @@
3941
import org.springframework.validation.SmartValidator;
4042

4143
/**
42-
* Adapter that takes a JSR-303 {@code javax.validator.Validator}
43-
* and exposes it as a Spring {@link org.springframework.validation.Validator}
44+
* Adapter that takes a JSR-303 {@code javax.validator.Validator} and
45+
* exposes it as a Spring {@link org.springframework.validation.Validator}
4446
* while also exposing the original JSR-303 Validator interface itself.
4547
*
4648
* <p>Can be used as a programmatic wrapper. Also serves as base class for
4749
* {@link CustomValidatorBean} and {@link LocalValidatorFactoryBean}.
4850
*
51+
* <p>Note that Bean Validation 1.1's {@code #forExecutables} method isn't supported
52+
* on this adapter: We do not expect that method to be called by application code;
53+
* consider {@link MethodValidationInterceptor} instead. If you really need programmatic
54+
* {@code #forExecutables} access, call {@code #unwrap(Validator.class) which will
55+
* provide the native {@link Validator} object with {@code #forExecutables} support.
56+
*
4957
* @author Juergen Hoeller
5058
* @since 3.0
5159
*/
@@ -297,7 +305,16 @@ public BeanDescriptor getConstraintsForClass(Class<?> clazz) {
297305
@SuppressWarnings("unchecked")
298306
public <T> T unwrap(Class<T> type) {
299307
Assert.state(this.targetValidator != null, "No target Validator set");
300-
return (type != null ? this.targetValidator.unwrap(type) : (T) this.targetValidator);
308+
try {
309+
return (type != null ? this.targetValidator.unwrap(type) : (T) this.targetValidator);
310+
}
311+
catch (ValidationException ex) {
312+
// ignore if just being asked for plain Validator
313+
if (Validator.class == type) {
314+
return (T) this.targetValidator;
315+
}
316+
throw ex;
317+
}
301318
}
302319

303320

0 commit comments

Comments
 (0)