我需要创建一个自定义约束注释,它可以访问我bean的另一个字段的值。我将使用这个注释来验证该字段,因为它取决于另一个的值,但是我定义它的方式编译器说“我的字段的注释属性的值”必须是一个常量表达式。
我已经用这种方式定义了它:
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy=EqualsFieldValidator.class)
@Documented
public @interface EqualsField {
public String field();
String message() default "{com.myCom.annotations.EqualsField.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
public class EqualsFieldValidator implements ConstraintValidator<EqualsField, String>{
private EqualsField equalsField;
@Override
public void initialize(EqualsField equalsField) {
this.equalsField = equalsField;
}
@Override
public boolean isValid(String thisField, ConstraintValidatorContext arg1) {
//my validation
}
}
在我的bean中我想要这样的东西:
public class MyBean{
private String field1;
@EqualsField(field=field1)
private String field2;
}
有没有办法定义注释,所以字段值可以是变量?
由于
答案 0 :(得分:13)
最简单的做法是退后一步:您编写的约束/验证器在字段级别上工作,但您要强制执行的是跨字段依赖,即类级别约束。
重写你的约束和验证器以在类级别工作(即注释将在类上,而不在字段上)。这样你就可以访问整个班级。在你的isValid(..)方法中,只需对两个字段进行get,比较并适当返回。
答案 1 :(得分:0)
正如编译器所说注释必须是常量的(即你可以在编译时确定值。)现在如果我正确猜测它看起来你正在使用这个注释来表示那些字段的值应当相等通过equals字段验证器。您可以采取的一种方法是使用反射。而不是尝试使用值进行注释,而是使用字段名称进行注释
public class MyBean{
private String field1;
@EqualsField("field1")
private String field2;
}
然后在您的验证器中,您可以阅读该字段的名称并使用反射来访问它
Object o = object.getClass().getDeclaredField(annotationValue).get(object);
o == object.(field with annotation) OR
o.equals(object.(field with annotation));
根据您的尝试,您可能需要根据字段类型添加逻辑,但仍然是相同的一般原则。
答案 2 :(得分:0)
查看上一个问题,有多个跨领域验证解决方案:Cross field validation with Hibernate Validator (JSR 303)