【问题标题】:Use Spring dependency injection on a custom Hibernate validator在自定义 Hibernate 验证器上使用 Spring 依赖注入
【发布时间】:2019-12-28 12:31:35
【问题描述】:

我想创建自己的 Hibernate 自定义验证器,我想做的是根据从不同上下文(不同的 Spring bean)收集的一些信息添加自定义逻辑

在我的自定义实现中,我尝试在 spring bean 中添加构造函数和定义验证器,或者使用 Autowire 注释,但它们都不起作用

自动装配示例:

public class MyCustomValidator implements ConstraintValidator<CustomConstraint, String> {
    @Autowired
    private MyCustomChecker customChecker;

    @Override
    public void initialize(CustomConstraint constraintAnnotation) {
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        if (null == value) {
            return true;
        }

        //get user authenticated properties to perform validation based on the user
        AuthenticatedIdentity identity = Context.getAuthenticatedIdentity();
        return customChecker.isWhitelisted(identity);
    }
}

构造函数示例:

public class MyCustomValidator implements ConstraintValidator<CustomConstraint, String> {

    private MyCustomChecker customChecker;

    public MetricDataSizeValidator(MyCustomChecker customChecker) {
        this.customChecker = customChecker;
    }

    @Override
    public void initialize(CustomConstraint constraintAnnotation) {
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        if (null == value) {
            return true;
        }

        //get user authenticated properties to perform validation based on the user
        AuthenticatedIdentity identity = Context.getAuthenticatedIdentity();
        return customChecker.isWhitelisted(identity);
    }
}

我在official Hibernate doc 上阅读过,但这并不能完全回答我的问题。

当您想根据来自不同上下文的某些信息进行验证时,我很确定这是一个常见问题,但是我没有找到答案。

我的应用正在使用 Spring DI,我的 bean 已经像这样初始化了

<bean id="customChecker" class="com.mycomp.CustomChecker">
    <constructor-arg>
        <value>arg</value>
    </constructor-arg>
</bean>

有没有关于如何实现这一点的示例?

更新

如果我将验证器配置为:

<bean id="validatorFactory" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
<bean id="validator" factory-bean="validatorFactory"
      factory-method="getValidator" />

现在我可以看到使用 spring bean 正确连接了验证。但是,现在我怀疑我是否正在使用 HibernateValidator(我想我不是)。有没有办法实现相同但配置 HibernateValidator 工厂以使用 Spring bean?

【问题讨论】:

  • @Vincz777 也许我没有抓住重点,但我没有看到自定义验证器上使用了任何依赖注入,我错了吗?
  • MyCustomValidator 类上方添加@Component 注释。 Spring应该注入MyCustomChecker
  • @AndreaGiuliano 您找到解决问题的方法了吗?

标签: java spring hibernate dependency-injection hibernate-validator


【解决方案1】:

我假设您的 MyCustomValidator 未被识别为托管 Spring bean,因此不会发生自动装配。

使您的 MyCustomValidator 成为 Spring bean 的最简单方法是在类级别添加 @Component 注释。

【讨论】:

  • 感谢您的评论。但是我尝试添加 @Component 并将注入与 Qualifier 一起使用,但仍然无法正常工作。我还应该在 CustomConstraint 接口定义中以某种方式更改 @Constraint(validatedBy = MyCustomValidator.class) 吗?
  • 你确保 spring 对 bean 进行类路径扫描吗?
  • 是的,我的大部分 bean 也被定义为一个 xml 文件。所以我也尝试在那里定义它而不是使用@Component注解,但仍然有“javax.validation.ValidationException:HV000064:无法实例化ConstraintValidator:”异常
  • 所以,有趣的是,我是否将 XML 中的验证器配置为 然后一切正常,但是我怀疑我实际上不再使用 HibernateValidator 了:/
【解决方案2】:

在 Spring MVC 的情况下,您可以使用 InitBinder,您的自定义验证器将由 RequestMappingHandlerAdapter 自动调用。 只需在控制器中使用 @InitBinder 注释您的方法,并在方法内部提供您的验证器并通过调用 webDataBinder.setValidator() 将您的验证器类提供给 WebDataBinder

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多