Поле переменной в аннотации ограничения

Мне нужно создать аннотацию пользовательского ограничения, которая может получить доступ к значению другого поля моего 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;
}

Есть ли способ определить аннотацию, поэтому значение поля может быть переменной?

Спасибо

Ответы

Ответ 1

Проще всего сделать один шаг назад: созданный вами механизм ограничения/валидатора работает на полевом уровне, но то, что вы хотите применить, - это зависимость поперечного поля, т.е. ограничение на уровне класса.

Перепишите свои ограничения и валидатор для работы на уровне класса (т.е. аннотация будет идти по классу, а не по полю). Таким образом, вы получите доступ ко всему классу. В вашем методе isValid (..) просто выполните поиск по обоим полям, сравните и верните соответствующим образом.

Ответ 2

Как компилятор сказал, что аннотации должны быть постоянными (т.е. вы можете определить значение во время компиляции.) Теперь, если я правильно угадываю, похоже, вы используете эту аннотацию, чтобы обозначить, что значения этих полей должны быть равны, если пройдите через валидатор поля равенства. Один из подходов, который вы можете предпринять, - это использовать отражение. Вместо того, чтобы пытаться аннотировать значение, вместо этого укажите вместо него имя поля

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

В зависимости от того, что вы пытаетесь сделать, вам может потребоваться добавить логику на основе типа поля, но все тот же общий принцип.