Java Hibernate验证程序-添加动态约束验证程序
在了解了之后,我对一个主题产生了兴趣,我是否可以创建一个基本注释,在其中设置要使用的验证器Java Hibernate验证程序-添加动态约束验证程序,java,hibernate,validation,annotations,hibernate-mapping,Java,Hibernate,Validation,Annotations,Hibernate Mapping,在了解了之后,我对一个主题产生了兴趣,我是否可以创建一个基本注释,在其中设置要使用的验证器 @Target({ ElementType.FIELD }) @Retention(RetentionPolicy.RUNTIME) @Constraint(validatedBy = validator().class) public @interface CustomAnnotation { public String message(); Class<?>[] group
@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();
}
我认为您不能在Hibernate验证器支持的基础上实现动态验证器解析器。最好有一组专用的注释验证器对,这样当您使用特定的验证注释对字段进行注释时,就可以清楚地知道将使用什么验证器了。我不推荐使用它,但您可以大致这样做:
@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);
}
}
您甚至可以通过META/validation.xml
文件将约束注释与实现链接起来
<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>
org.mycompany.EnumCustomValidatorImpl
如果你需要更灵活的方式,我想我最初的建议会奏效。在
genericvalidaterbootstrappervalidator
isValid方法中,您可以根据value
参数的对象类型调用正确的验证器实例(例如,通过instanceof
).Hibernate Validator现在还提供了一个注释,它使自定义验证的实现更加容易,并有助于避免大量代码行
使用示例:
@ScriptAssert(lang = "javascript",
script = "_this.capital.equals(_this.capital.toUpperCase)",
message = "capital has not Capital letters")
public class BigLetters {
private String capital;
public String getCapital() {
return capital;
}
public void setCapital(String capital) {
this.capital = capital;
}
}
即使相关注释之间的差异是要验证的数据(即,值在枚举或迭代中)?也可以将
@CustomAnnotation.message()
的值设置为GenericValidatorBootstrapperValidator.initialize()
?Hi@KaidoShugo,我想我不理解你的问题:)你在谈论哪个枚举或迭代?此外,由于提供了注释本身,GenericValidatorBootstrapperValidator.initialize()也可以使用CustomAnnotation.message()。顺便说一句,注释不能子类化。这就是你一开始想做的吗?这在Java中是不可行的。我将尝试创建一个Bitbucket存储库来解释我的问题。但基本上,问题是创建一个@CustomAnnotation
,其中可以按照问题中的格式将验证器设置为参数。因为我几乎有几个验证器,其中唯一的区别是要从中进行验证的数据源(例如,枚举、列表、表等)。这就是我当前的实现。尽管相关的注释具有几乎相似的验证,但在待验证数据的值上存在差异?我希望这可以通过注释上的抽象(如果存在的话)来实现。尝试将验证逻辑移动到一个单独的CommonValidator,每个单独的验证器在定义其特定逻辑的同时也将继承CommonValidator逻辑。因此,您是说遵循“Emmanuel Bernard”的实现?Emmanuel是Hibernate验证项目负责人,因此他最清楚。
@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) {
}
}
<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>
@ScriptAssert(lang = "javascript",
script = "_this.capital.equals(_this.capital.toUpperCase)",
message = "capital has not Capital letters")
public class BigLetters {
private String capital;
public String getCapital() {
return capital;
}
public void setCapital(String capital) {
this.capital = capital;
}
}