Hibernate验证 - 添加动态ConstraintValidator [英] Hibernate Validator - Add a Dynamic ConstraintValidator

查看:501
本文介绍了Hibernate验证 - 添加动态ConstraintValidator的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

学习<一后href=\"https://docs.jboss.org/hibernate/validator/4.0.1/reference/en/html/validator-customconstraints.html\"相对=nofollow> Hibernate的自定义验证,它给了我一个主题感兴趣,我可不可以创建一个基地注释,其中我可以设置要使用的验证?

  @Target({} ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy =验证器()。类)
公共@interface CustomAnnotation {
    公共字符串消息();
    类&LT;&GT; []群()默认{};
    类&LT ;?扩展有效载荷GT; []的有效载荷()默认{};
    类&LT ;?扩展ConstraintValidator&LT ;?扩展CustomAnnotation,序列化&GT;&GT;验证器();
}

所以,我可以用 @CustomAnnotation 以这种方式

  @CustomAnnotation(验证= CustomConstraintValidator.class,消息=validationMessage)
私有对象字段名;


解决方案

我不会推荐它,但你可以做到这一点大致是这样的:

  @Target({} ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = GenericValidatorBootstrapperValidator.class)
公共@interface CustomAnnotation {
    公共字符串消息();
    类&LT;&GT; []群()默认{};
    类&LT ;?扩展有效载荷GT; []的有效载荷()默认{};
    类&LT ;?扩展ConstraintValidator&LT ;?扩展CustomAnnotation,序列化&GT;&GT;验证器();
}公共类GenericValidatorBootstrapperValidator实现ConstraintValidator&LT; CustomAnnotation,对象&gt; {    私人最终ConstraintValidator验证;    @覆盖
    公共无效初始化(CustomAnnotation constraintAnnotation){
        类&LT ;?扩展ConstraintValidator&GT; validatorClass = constraintAnnotation.validator();
        验证= validatorClass.newInstance();
        validator.initialize(...); // TODO什么?
    }    @覆盖
    公共布尔的isValid(对象的值,ConstraintValidatorContext上下文){
        返回validator.isValid(值,背景);
    }
}

但同样,preFER具体的注解,他们更前pressive。

修改

您的评论后,我想你想要的是能够根据返回类型属性的

要设置不同的验证器

  @CustomAnnotation
清单&LT;串GT;富;@CustomAnnotation
表吧;

如果是这样的话,在 @Constraint 标注添加几个验证器的实现。

  @Target({} ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {ListValidatorImpl.class,TableValidatorImpl.class,...})
公共@interface CustomAnnotation {
    公共字符串消息();
    类&LT;&GT; []群()默认{};
    类&LT ;?扩展有效载荷GT; []的有效载荷()默认{};
}公共类ListValidatorImpl实现ConstraintValidator&LT; CustomAnnotation,列表&gt; {    @覆盖
    公共布尔的isValid(List值,ConstraintValidatorContext上下文){
    }
}公共类TableValidatorImpl实现ConstraintValidator&LT; CustomAnnotation,表&gt; {    @覆盖
    公共布尔的isValid(表值,ConstraintValidatorContext上下文){
    }
}

您甚至可以链接约束实现批注与通过 META / validation.xml中实施文件

 &LT;约束映射
    XMLNS:XSI =htt​​p://www.w3.org/2001/XMLSchema-instance
    XSI:的schemaLocation =htt​​p://jboss.org/xml/ns/javax/validation/mapping~~V验证映射,1.1.xsd
    的xmlns =htt​​p://jboss.org/xml/ns/javax/validation/mapping版本=1.1&GT;    &LT;约束定义注释=org.mycompany.CustomAnnotation&GT;
        &LT;验证,通过包括现有-验证=真正的&GT;
            &LT; VALUE&GT; org.mycompany.EnumCustomValidatorImpl&LT; /值&GT;
        &LT; /验证,通过&GT;
    &LT; /约束的定义&GT;
&LT; /约束的映射&GT;

如果你需要的东西更灵活,我想我的初步建议是可行的。在 GenericValidatorBootstrapperValidator 的isValid方法,你可以根据参数的对象类型调用正确的校验器实例(通过的instanceof 为例)。

After learning about Hibernate Custom Validators, it has given me an interest in one topic, could I possibly create one base annotation wherein I could set which Validator to use?

@Target({ ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = validator().class)
public @interface CustomAnnotation {
    public String message();
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
    Class<? extends ConstraintValidator<? extends CustomAnnotation, Serializable>> validator();
}

So that I could use @CustomAnnotation in this manner

@CustomAnnotation(validator = CustomConstraintValidator.class, message = "validationMessage")
private Object fieldName;

解决方案

I would not recommend it but you can do it roughly this way:

@Target({ ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = GenericValidatorBootstrapperValidator.class)
public @interface CustomAnnotation {
    public String message();
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
    Class<? extends ConstraintValidator<? extends CustomAnnotation, Serializable>> validator();
}

public class GenericValidatorBootstrapperValidator implements ConstraintValidator<CustomAnnotation, Object> {

    private final ConstraintValidator validator;

    @Override
    public void initialize(CustomAnnotation constraintAnnotation) {
        Class<? extends ConstraintValidator> validatorClass = constraintAnnotation.validator();
        validator = validatorClass.newInstance();
        validator.initialize( ... ); //TODO with what?
    }

    @Override
    public boolean isValid(Object value, ConstraintValidatorContext context) {
        return validator.isValid(value, context);
    }
}

But again, prefer specific annotations, they are more expressive.

Edit

After your comment, I think what you want is to be able to set different validators based on the return type of the property

@CustomAnnotation
List<String> foo;

@CustomAnnotation
Table bar;

If that's the case, add several validators implementations in the @Constraint annotation.

@Target({ ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {ListValidatorImpl.class, TableValidatorImpl.class, ...})
public @interface CustomAnnotation {
    public String message();
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

public class ListValidatorImpl implements ConstraintValidator<CustomAnnotation, List> {

    @Override
    public boolean isValid(List value, ConstraintValidatorContext context) {
    }
}

public class TableValidatorImpl implements ConstraintValidator<CustomAnnotation, Table> {

    @Override
    public boolean isValid(Table value, ConstraintValidatorContext context) {
    }
}

You can even link a contraint annotation with an implementation via the META/validation.xml file

<constraint-mappings
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://jboss.org/xml/ns/javax/validation/mapping validation-mapping-1.1.xsd"
    xmlns="http://jboss.org/xml/ns/javax/validation/mapping" version="1.1">

    <constraint-definition annotation="org.mycompany.CustomAnnotation">
        <validated-by include-existing-validators="true">
            <value>org.mycompany.EnumCustomValidatorImpl</value>
        </validated-by>
    </constraint-definition>
</constraint-mappings>

If you need something more flexible, I think my initial proposal would work. In the GenericValidatorBootstrapperValidator isValid method, you could call the right validator instance based on the object type of the value parameter (via instanceof for example).

这篇关于Hibernate验证 - 添加动态ConstraintValidator的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆