在了解了Hibernate Custom Validators之后,它让我对一个主题感兴趣,我是否可以创建一个基本注释,其中我可以设置使用哪个Validator?
@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
@CustomAnnotation(validator = CustomConstraintValidator.class, message = "validationMessage")
private Object fieldName;
答案 0 :(得分:7)
我不推荐它,但你可以大致这样做:
@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);
}
}
但同样,更喜欢特定的注释,它们更具表现力。
在您发表评论之后,我认为您想要的是能够根据属性的返回类型设置不同的验证器
@CustomAnnotation
List<String> foo;
@CustomAnnotation
Table bar;
如果是这种情况,请在@Constraint
注释中添加几个验证器实现。
@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
文件
<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
)。
答案 1 :(得分:1)
Hibernate Validator现在还提供了一个注释@ScriptAssert,它使自定义验证的实现更容易,并有助于避免大量代码。
使用示例:
@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;
}
}
答案 2 :(得分:0)
我认为您不能在Hibernate Validator支持的基础上实现动态验证器解析器。拥有一组专用的注释 - 验证器对会好得多,因此当您使用特定的验证注释注释某个字段时,它会明确使用哪个验证器。