覆盖 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 使用上面的而不是扩展 LocalValidatorFactoryBeanOptionalValidatorFactoryBean我认为是根据来自 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;
}