#jsf-2 #validation #resourcebundle #hibernate-validator #bean-validation
#jsf-2 #проверка #resourcebundle #переход в спящий режим-валидатор #проверка компонента
Вопрос:
Я написал средство проверки JSR303, которое сравнивает значение свойства с ограничением:
@Documented
@Constraint(validatedBy = Cmp.LongCmpValidator.class)
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
@Retention(RUNTIME)
public @interface Cmp {
String message() default "{home.lang.validator.Cmp.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
long value();
public enum REL { LT,LT_EQ,EQ,GT,GT_EQ;
@Override
public String toString() {
return toString_property();
}
public String toString_property() {
switch(this) {
case LT : return "{home.lang.validator.Cmp.REL.LT}";
case LT_EQ: return "{home.lang.validator.Cmp.REL.LT_EQ}";
case EQ: return "{home.lang.validator.Cmp.REL.EQ}";
case GT : return "{home.lang.validator.Cmp.REL.GT}";
case GT_EQ: return "{home.lang.validator.Cmp.REL.GT_EQ}";
}
throw new UnsupportedOperationException();
}
public String toString_common() { return super.toString(); }
public String toString_math() { switch(this) {
case LT : return "<";
case LT_EQ: return "u2264";
case EQ: return "=";
case GT : return ">";
case GT_EQ: return "u2265";
}
throw new UnsupportedOperationException();
}
}
REL prop_rel_cnstr();
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
@Retention(RUNTIME)
@Documented
@interface List {
Cmp[] value();
}
class LongCmpValidator implements ConstraintValidator<Cmp, Number> {
long cnstr_val;
REL prop_rel_cnstr;
public void initialize(Cmp constraintAnnotation) {
cnstr_val = constraintAnnotation.value();
prop_rel_cnstr = constraintAnnotation.prop_rel_cnstr();
}
public boolean isValid(Number _value, ConstraintValidatorContext context) {
if(_value == null) return true;
if(_value instanceof Integer) {
int value = _value.intValue();
switch(prop_rel_cnstr) {
case LT : return value < cnstr_val;
case LT_EQ: return value <= cnstr_val;
case EQ: return value == cnstr_val;
case GT : return value > cnstr_val;
case GT_EQ: return value >= cnstr_val;
}
}
// ... handle other types
return true;
}
}
}
Сообщения проверки.свойства :
home.lang.validator.Cmp.REL.LT=less than
home.lang.validator.Cmp.REL.LT_EQ=less than or equal
home.lang.validator.Cmp.REL.EQ=equal
home.lang.validator.Cmp.REL.GT=greater
home.lang.validator.Cmp.REL.GT_EQ=greater than or equal
home.lang.validator.Cmp.message=Failure: validated value is to be in relation "{prop_rel_cnstr}" to {value}.
Работает нормально. Почти. Сообщение о проверке, которое я получаю, выглядит следующим образом:
Failure: validated value is to be in relation "{home.lang.validator.Cmp.REL.GT}" to 0.
Кто-нибудь, пожалуйста, может предложить простой и удобный способ, как заставить валидатор распознавать и разрешать вложенные {home.lang.validator.Cmp.REL.GT } ключ? Мне нужно, чтобы это было удобно использовать в JSF2, который обрабатывает проверку.
Я не использую Spring, но использую hibernate-validator 4.
Кстати, похоже, что hibernate-validator 4 не полностью реализует JSR303, поскольку более поздние состояния в 4.3.1.1.:
- Параметры сообщения извлекаются из строки сообщения и используются в качестве ключей для поиска в каталоге ресурсов с именем ValidationMessages (часто материализуется как файл свойств / ValidationMessages.properties и его языковые вариации) с использованием определенного языка (см. Ниже). Если свойство найдено, параметр сообщения заменяется значением свойства в строке сообщения. Шаг 1 применяется рекурсивно до тех пор, пока не будет выполнена замена (т. Е. значение параметра сообщения само может содержать параметр сообщения).
Ответ №1:
Хорошо, я покопался в этом. Алгоритм, указанный в JSR303, имеет неинтуитивную путаницу с тем, что (реквизиты) рекурсивно разрешимы, а что нет. Я думаю, это в основном из-за плохого различия в грамматике свойств аннотации и свойств RB.
Итак, я создал свой собственный MessageInterpolator, который вы можете найти в моем репозитории:http://github.com/Andrey-Sisoyev/adv-msg-interpolator. Это решает почти все проблемы, а также позволяет обратиться к набору ресурсов, где искать свойство.