问题说明
当使用带有 Spring-MVC 4 的 Hibernate Validator (HV) 4.2 时,例如带有依赖项:
dependencies {
providedCompile 'javax.servlet:javax.servlet-api:3.0.1'
compile 'org.springframework:spring-webmvc:4.0.3.RELEASE'
compile 'org.hibernate:hibernate-validator:4.2.0.Final'
runtime 'javax.servlet:jstl:1.1.2'
}
@Validated
可以通过在配置文件中声明以下 bean来告诉 Spring 自动使用 HV 来验证带有注释的类的方法调用(如在 asker 的示例中),
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
<bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor"/>
当目标的方法被调用并且有一些违反其约束的东西时,将MethodConstraintViolationException
被抛出。例如,如果一个人碰巧调用UserService#registerUser(...)
,就会引发类似这样的事情,将一个空字符串传递给带有注释的地方@NotEmpty
... The following constraint violations occurred: [MethodConstraintViolationImpl
[method=public abstract void foo.UserService.registerUser(java.lang.String),
parameterIndex=0, parameterName=arg0, kind=PARAMETER, message=may not be empty,
messageTemplate={org.hibernate.validator.constraints.NotEmpty.message}, ...
但问题是,如果您将依赖项从上面更改为
dependecies {
providedCompile 'javax.servlet:javax.servlet-api:3.0.1'
compile 'org.springframework:spring-webmvc:4.0.3.RELEASE'
compile 'org.hibernate:hibernate-validator:5.1.0.Final' //**note the change here**
runtime 'javax.servlet:jstl:1.1.2'
}
那么你会得到一个错误:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name
'org.springframework.validation.beanvalidation.MethodValidationPostProcessor#0'
defined in class path resource [spring/config/web/main-config.xml]: Invocation of init
method failed; nested exception is javax.validation.ValidationException: Unable to
instantiate Configuration.
解决方案
向类路径添加 2 个额外的依赖项,如下所示,
dependecies {
providedCompile 'javax.servlet:javax.servlet-api:3.0.1'
providedCompile 'javax.el:el-api:2.2'
providedCompile 'org.glassfish.web:el-impl:2.2'
compile 'org.springframework:spring-webmvc:4.0.3.RELEASE'
compile 'org.hibernate:hibernate-validator:5.1.0.Final' //**note the change here**
runtime 'javax.servlet:jstl:1.1.2'
}
验证将恢复活力。但这一次,MethodConstraintViolationException
它没有提出ConstranitViolationException
任何违反的细节,而不是 。
我不确定 Spring 如何在内部管理这个问题,以及你是否可以从这个异常中展开违规细节。HV 5 不再支持MethodConstraintViolationException
及其亲属,MethodValidator
例如MethodConstraintViolation
. 这与Bean Validation 1.1 规范有关,它在 BV 1.0 的方法级验证方面有一些变化。我建议您自己使用 aspect 和 with ExecutableValidator
(而不是 old MethodValidator
)创建验证服务,如HV's Reference guide中所述。
请注意,如果您尝试像这样获取验证器,
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
ExecutableValidator executableValidator = factory.getValidator().forExecutables();
你可能会得到ValidationException: Unable to instantiate configuration.
我可以通过这样做来解决这个问题
ValidatorFactory factory = Validation.byProvider(HibernateValidator.class).configure().buildValidatorFactory();
ExecutableValidator executableValidator = factory.getValidator().forExecutables();