Поле переменной в аннотации ограничения
Мне нужно создать аннотацию пользовательского ограничения, которая может получить доступ к значению другого поля моего 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));
В зависимости от того, что вы пытаетесь сделать, вам может потребоваться добавить логику на основе типа поля, но все тот же общий принцип.
Ответ 3
Посмотрите на этот предыдущий вопрос, есть несколько решений для проверки в кросс-поле: Проверка полей с помощью Hibernate Validator (JSR 303)