Переменное поле в аннотации ограничения - PullRequest
13 голосов
/ 18 марта 2010

Мне нужно создать пользовательскую аннотацию ограничения, которая может получить доступ к значению другого поля моего компонента. Я буду использовать эту аннотацию для проверки поля, потому что оно зависит от значения другого, но как я его определяю, компилятор говорит: «Значение атрибута аннотации« моего поля »должно быть постоянным выражением».

Я определил это так:

@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
    }

}

и в моем бобе я хочу что-то вроде этого:

public class MyBean{

     private String field1;

     @EqualsField(field=field1)
     private String field2;
}

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

Спасибо

Ответы [ 3 ]

13 голосов
/ 18 марта 2010

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

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

0 голосов
/ 09 июля 2010

Проверьте этот предыдущий вопрос, есть несколько решений для проверки по нескольким полям: Проверка по полям с помощью Hibernate Validator (JSR 303)

0 голосов
/ 18 марта 2010

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

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

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

...