Support multiple Validators in DataBinder
DataBinder now allows registering additional Validator instances. This may be useful when adding a Spring Validator to a globally registered JSR-303 LocalValidatorFactoryBean. Issue: SPR-9436
This commit is contained in:
@@ -18,7 +18,11 @@ package org.springframework.validation;
|
||||
|
||||
import java.beans.PropertyEditor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
@@ -141,7 +145,7 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
|
||||
|
||||
private BindingErrorProcessor bindingErrorProcessor = new DefaultBindingErrorProcessor();
|
||||
|
||||
private Validator validator;
|
||||
private final List<Validator> validators = new ArrayList<Validator>();
|
||||
|
||||
private ConversionService conversionService;
|
||||
|
||||
@@ -493,21 +497,58 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
|
||||
|
||||
/**
|
||||
* Set the Validator to apply after each binding step.
|
||||
* @see #addValidators(Validator...)
|
||||
* @see #replaceValidators(Validator...)
|
||||
*/
|
||||
public void setValidator(Validator validator) {
|
||||
if (validator != null && (getTarget() != null && !validator.supports(getTarget().getClass()))) {
|
||||
throw new IllegalStateException("Invalid target for Validator [" + validator + "]: " + getTarget());
|
||||
assertValidators(validator);
|
||||
this.validators.clear();
|
||||
this.validators.add(validator);
|
||||
}
|
||||
|
||||
private void assertValidators(Validator... validators) {
|
||||
Assert.notNull(validators, "Validators required");
|
||||
for (Validator validator : validators) {
|
||||
if (validator != null && (getTarget() != null && !validator.supports(getTarget().getClass()))) {
|
||||
throw new IllegalStateException("Invalid target for Validator [" + validator + "]: " + getTarget());
|
||||
}
|
||||
}
|
||||
this.validator = validator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Validator to apply after each binding step, if any.
|
||||
* Add Validators to apply after each binding step.
|
||||
* @see #setValidator(Validator)
|
||||
* @see #replaceValidators(Validator...)
|
||||
*/
|
||||
public Validator getValidator() {
|
||||
return this.validator;
|
||||
public void addValidators(Validator... validators) {
|
||||
assertValidators(validators);
|
||||
this.validators.addAll(Arrays.asList(validators));
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace the Validators to apply after each binding step.
|
||||
* @see #setValidator(Validator)
|
||||
* @see #addValidators(Validator...)
|
||||
*/
|
||||
public void replaceValidators(Validator... validators) {
|
||||
assertValidators(validators);
|
||||
this.validators.clear();
|
||||
this.validators.addAll(Arrays.asList(validators));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the primary Validator to apply after each binding step, if any.
|
||||
*/
|
||||
public Validator getValidator() {
|
||||
return this.validators.size() > 0 ? this.validators.get(0) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Validators to apply after data binding.
|
||||
*/
|
||||
public List<Validator> getValidators() {
|
||||
return Collections.unmodifiableList(this.validators);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Implementation of PropertyEditorRegistry/TypeConverter interface
|
||||
@@ -708,28 +749,31 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
|
||||
|
||||
|
||||
/**
|
||||
* Invoke the specified Validator, if any.
|
||||
* Invoke the specified Validators, if any.
|
||||
* @see #setValidator(Validator)
|
||||
* @see #getBindingResult()
|
||||
*/
|
||||
public void validate() {
|
||||
this.validator.validate(getTarget(), getBindingResult());
|
||||
for (Validator validator : this.validators) {
|
||||
validator.validate(getTarget(), getBindingResult());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke the specified Validator, if any, with the given validation hints.
|
||||
* Invoke the specified Validators, if any, with the given validation hints.
|
||||
* <p>Note: Validation hints may get ignored by the actual target Validator.
|
||||
* @param validationHints one or more hint objects to be passed to a {@link SmartValidator}
|
||||
* @see #setValidator(Validator)
|
||||
* @see SmartValidator#validate(Object, Errors, Object...)
|
||||
*/
|
||||
public void validate(Object... validationHints) {
|
||||
Validator validator = getValidator();
|
||||
if (!ObjectUtils.isEmpty(validationHints) && validator instanceof SmartValidator) {
|
||||
((SmartValidator) validator).validate(getTarget(), getBindingResult(), validationHints);
|
||||
}
|
||||
else if (validator != null) {
|
||||
validator.validate(getTarget(), getBindingResult());
|
||||
for (Validator validator : getValidators()) {
|
||||
if (!ObjectUtils.isEmpty(validationHints) && validator instanceof SmartValidator) {
|
||||
((SmartValidator) validator).validate(getTarget(), getBindingResult(), validationHints);
|
||||
}
|
||||
else if (validator != null) {
|
||||
validator.validate(getTarget(), getBindingResult());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user