覆盖 spring web mvc 的默认 Hibernate Validator
Override spring web mvc's default Hibernate Validator
Spring 正在使用 hibernate 工厂提供的默认验证器工厂。但是,我不想包含表达式语言依赖项。
此 answer 建议通过以下代码避免使用默认工厂:
import javax.validation.Validation;
import javax.validation.Validator;
import org.hibernate.validator.messageinterpolation.ParameterMessageInterpolator;
private static final Validator VALIDATOR =
Validation.byDefaultProvider()
.configure()
.messageInterpolator(new ParameterMessageInterpolator())
.buildValidatorFactory()
.getValidator();
当我引用 VALIDATOR 时效果很好,但我不确定如何告诉 spring 使用上面的而不是扩展 LocalValidatorFactoryBean
的 OptionalValidatorFactoryBean
我认为是根据来自 LocalValidatorFactoryBean
的 javadoc 使用来自 Validation.buildDefaultValidatorFactory()
的验证器填充的
总而言之,如何将 spring 的默认值 Validation.buildDefaultValidatorFactory()
替换为 Validation.byDefaultProvider().configure().messageInterpolator(new ParameterMessageInterpolator()).buildValidatorFactory().getValidator()
这样我就可以避免对表达式语言的依赖。
尝试查看 Configuring a Bean Validation Provider for some discussion of the Validation Provider mechanism, and, for example, Spring-driven Method Validation,然后将其作为默认方法验证 bean 注入。
<bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor">
<property name="validatorFactory" ref="myValidatorFactory"/>
</bean>
(我在 WebSphere Application Server here 上用 Spring 4.x 做了这种事情。)
感谢@dbreaux 的回答,我查阅了文档并提出了这个解决方案:
@Bean
public LocalValidatorFactoryBean validator() {
LocalValidatorFactoryBean localValidatorFactoryBean = new LocalValidatorFactoryBean();
localValidatorFactoryBean.setMessageInterpolator(new ParameterMessageInterpolator());
return localValidatorFactoryBean;
}
我不再需要 Expression Language 依赖项,我的验证正在使用 Hibernate Validator 5.2.5.Final
。
但是,由于安全问题,我不得不升级到 6.0.22.Final
并切换到下面非常接近@dbreaux 的。我还必须将@Validated 添加到@Controller。
@Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
MethodValidationPostProcessor bean = new MethodValidationPostProcessor();
bean.setValidator(Validation.byDefaultProvider()
.configure()
// We must use ParameterMessageInterpolator so that we do not need to add a dependency
// on Java Expression Language which is a potential security vulnerability.
// See https://securitylab.github.com/research/bean-validation-RCE/ for more info.
.messageInterpolator(new ParameterMessageInterpolator())
.buildValidatorFactory()
.getValidator());
return bean;
}
Spring 正在使用 hibernate 工厂提供的默认验证器工厂。但是,我不想包含表达式语言依赖项。
此 answer 建议通过以下代码避免使用默认工厂:
import javax.validation.Validation;
import javax.validation.Validator;
import org.hibernate.validator.messageinterpolation.ParameterMessageInterpolator;
private static final Validator VALIDATOR =
Validation.byDefaultProvider()
.configure()
.messageInterpolator(new ParameterMessageInterpolator())
.buildValidatorFactory()
.getValidator();
当我引用 VALIDATOR 时效果很好,但我不确定如何告诉 spring 使用上面的而不是扩展 LocalValidatorFactoryBean
的 OptionalValidatorFactoryBean
我认为是根据来自 LocalValidatorFactoryBean
Validation.buildDefaultValidatorFactory()
的验证器填充的
总而言之,如何将 spring 的默认值 Validation.buildDefaultValidatorFactory()
替换为 Validation.byDefaultProvider().configure().messageInterpolator(new ParameterMessageInterpolator()).buildValidatorFactory().getValidator()
这样我就可以避免对表达式语言的依赖。
尝试查看 Configuring a Bean Validation Provider for some discussion of the Validation Provider mechanism, and, for example, Spring-driven Method Validation,然后将其作为默认方法验证 bean 注入。
<bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor">
<property name="validatorFactory" ref="myValidatorFactory"/>
</bean>
(我在 WebSphere Application Server here 上用 Spring 4.x 做了这种事情。)
感谢@dbreaux 的回答,我查阅了文档并提出了这个解决方案:
@Bean
public LocalValidatorFactoryBean validator() {
LocalValidatorFactoryBean localValidatorFactoryBean = new LocalValidatorFactoryBean();
localValidatorFactoryBean.setMessageInterpolator(new ParameterMessageInterpolator());
return localValidatorFactoryBean;
}
我不再需要 Expression Language 依赖项,我的验证正在使用 Hibernate Validator 5.2.5.Final
。
但是,由于安全问题,我不得不升级到 6.0.22.Final
并切换到下面非常接近@dbreaux 的。我还必须将@Validated 添加到@Controller。
@Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
MethodValidationPostProcessor bean = new MethodValidationPostProcessor();
bean.setValidator(Validation.byDefaultProvider()
.configure()
// We must use ParameterMessageInterpolator so that we do not need to add a dependency
// on Java Expression Language which is a potential security vulnerability.
// See https://securitylab.github.com/research/bean-validation-RCE/ for more info.
.messageInterpolator(new ParameterMessageInterpolator())
.buildValidatorFactory()
.getValidator());
return bean;
}