默认就是用下面的这个validator
/** * {@link LocalValidatorFactoryBean} subclass that simply turns * {@link org.springframework.validation.Validator} calls into no-ops * in case of no Bean Validation provider being available. * * <p>This is the actual class used by Spring's MVC configuration namespace, * in case of the {@code javax.validation} API being present but no explicit * Validator having been configured. * * @author Juergen Hoeller * @since 4.0.1 */ public class OptionalValidatorFactoryBean extends LocalValidatorFactoryBean { @Override public void afterPropertiesSet() { try { super.afterPropertiesSet(); } catch (ValidationException ex) { LogFactory.getLog(getClass()).debug("Failed to set up a Bean Validation provider", ex); } } }
是在WebMvcConfigurationSupport中决定的
引用
/**
* Return a global {@link Validator} instance for example for validating
* {@code @ModelAttribute} and {@code @RequestBody} method arguments.
* Delegates to {@link #getValidator()} first and if that returns {@code null}
* checks the classpath for the presence of a JSR-303 implementations
* before creating a {@code OptionalValidatorFactoryBean}.If a JSR-303
* implementation is not available, a no-op {@link Validator} is returned.
*/
@Bean
public Validator mvcValidator() {
Validator validator = getValidator();
if (validator == null) {
if (ClassUtils.isPresent("javax.validation.Validator", getClass().getClassLoader())) {
Class<?> clazz;
try {
String className = "org.springframework.validation.beanvalidation.OptionalValidatorFactoryBean";
clazz = ClassUtils.forName(className, WebMvcConfigurationSupport.class.getClassLoader());
}
catch (ClassNotFoundException ex) {
throw new BeanInitializationException("Could not find default validator class", ex);
}
catch (LinkageError ex) {
throw new BeanInitializationException("Could not load default validator class", ex);
}
validator = (Validator) BeanUtils.instantiate(clazz);
}
else {
validator = new NoOpValidator();
}
}
return validator;
}
* Return a global {@link Validator} instance for example for validating
* {@code @ModelAttribute} and {@code @RequestBody} method arguments.
* Delegates to {@link #getValidator()} first and if that returns {@code null}
* checks the classpath for the presence of a JSR-303 implementations
* before creating a {@code OptionalValidatorFactoryBean}.If a JSR-303
* implementation is not available, a no-op {@link Validator} is returned.
*/
@Bean
public Validator mvcValidator() {
Validator validator = getValidator();
if (validator == null) {
if (ClassUtils.isPresent("javax.validation.Validator", getClass().getClassLoader())) {
Class<?> clazz;
try {
String className = "org.springframework.validation.beanvalidation.OptionalValidatorFactoryBean";
clazz = ClassUtils.forName(className, WebMvcConfigurationSupport.class.getClassLoader());
}
catch (ClassNotFoundException ex) {
throw new BeanInitializationException("Could not find default validator class", ex);
}
catch (LinkageError ex) {
throw new BeanInitializationException("Could not load default validator class", ex);
}
validator = (Validator) BeanUtils.instantiate(clazz);
}
else {
validator = new NoOpValidator();
}
}
return validator;
}
这个地方开始进入验证
ModelAttributeMethodProcessor:
1.resolveArgument
{
这个地方有创建binder
WebDataBinder binder = binderFactory.createBinder(webRequest, attribute, name);
}
this.initializer.initBinder(dataBinder, webRequest);
这句话最重要
/** * Create a new {@link WebDataBinder} for the given target object and * initialize it through a {@link WebBindingInitializer}. * @throws Exception in case of invalid state or arguments */ @Override public final WebDataBinder createBinder(NativeWebRequest webRequest, Object target, String objectName) throws Exception { WebDataBinder dataBinder = createBinderInstance(target, objectName, webRequest); if (this.initializer != null) { this.initializer.initBinder(dataBinder, webRequest); } initBinder(dataBinder, webRequest); return dataBinder; } 这个地方有初始化 ConfigurableWebBindingInitializer:initBinder
2.validateIfApplicable
DataBinder: validate
DataBinder中含有
private final List<Validator> validators = new ArrayList<Validator>();
真实的验证发生在
SpringValidatorAdapter 中targetValidator的validate
他的实现可以是hibernate中的ValidatorImpl
public Validator getValidator() { ResourceBundleLocator defaultResourceBundleLocator = new PlatformResourceBundleLocator(VALIDATION_FILE_NAME); MessageInterpolator defaultMessageInterpolator = new ResourceBundleMessageInterpolator( defaultResourceBundleLocator); LocalValidatorFactoryBean bean = new LocalValidatorFactoryBean(); bean.setMessageInterpolator(defaultMessageInterpolator); bean.setProviderClass(HibernateValidator.class); // bean.setValidationMessageSource(messageSource()); return bean; }
上面的可以使用hibernate默认的错误信息
同时包含自定义的错误信息
注意VALIDATION_FILE_NAME不能包含classpath
可以看可以有文件夹