约束注释中的变量字段

我需要创建一个自定义约束注释,它可以访问我的bean的另一个字段的值。 我将使用此注释来validation该字段,因为它取决于另一个的值,但是我定义它的方式编译器说“我的字段的注释属性的值”必须是一个常量表达式。

我用这种方式定义了它:

@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[] payload() default {}; } public class EqualsFieldValidator implements ConstraintValidator{ private EqualsField equalsField; @Override public void initialize(EqualsField equalsField) { this.equalsField = equalsField; } @Override public boolean isValid(String thisField, ConstraintValidatorContext arg1) { //my validation } } 

在我的豆子里我想要这样的东西:

 public class MyBean{ private String field1; @EqualsField(field=field1) private String field2; } 

有没有办法定义注释,所以字段值可以是一个变量?

谢谢

最简单的做法是退后一步:您编写的约束/validation器在字段级别上工作,但您要强制执行的是跨字段依赖性,即类级别约束。

重写您的约束和validation器以在类级别工作(即注释将在类上,而不是在字段上)。 这样你就可以访问整个class级。 在你的isValid(..)方法中,只需在两个字段上执行get,比较并适当返回。

正如编译器所说注释必须是常量的(即你可以在编译时确定值。)现在,如果我猜对了,看起来你正在使用这个注释来表示这些字段的值在运行时应该相等等于字段validation器。 您可以采取的一种方法是使用reflection。 而不是尝试使用值进行注释,而是使用字段名称进行注释

 public class MyBean{ private String field1; @EqualsField("field1") private String field2; } 

然后在validation器中,您可以读取字段的名称并使用reflection来访问它

 Object o = object.getClass().getDeclaredField(annotationValue).get(object); o == object.(field with annotation) OR o.equals(object.(field with annotation)); 

根据您的尝试,您可能需要根据字段类型添加逻辑,但仍然是相同的一般原则。

看看上一个问题,有多个跨领域validation解决方案: 使用Hibernate Validator进行交叉字段validation(JSR 303)