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

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

问题描述

了解Hibernate Custom Validators之后,它让我对一个主题产生了兴趣,我是否可以创建一个基本注释,其中我可以设置要使用的验证器?

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();
}

这样我就可以以这种方式使用 @CustomAnnotation

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.

在您发表评论后,我认为您想要的是能够根据属性的返回类型设置不同的验证器

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;

如果是这种情况,请在 @Constraint 注释中添加几个验证器实现.

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) {
    }
}

您甚至可以通过 META/validation.xml 文件将约束注释与实现链接起来

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>

如果你需要更灵活的东西,我认为我最初的建议会奏效.在 GenericValidatorBootstrapperValidator isValid 方法中,您可以根据 value 参数的对象类型(例如通过 instanceof)调用正确的验证器实例.

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 Validator - 添加动态 ConstraintValidator的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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