我编写了一个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;
}
}
}
ValidationMessages.properties:
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.
有人请建议简单方便的方法,如何让Validator识别并解析嵌套的{home.lang.validator.Cmp.REL.GT}键?我需要它在JSF2中很好地使用,它处理验证。 我不是在使用Spring,而是使用hibernate-validator 4。
顺便说一句,看起来hibernate-validator 4并没有完全实现JSR303,因为后来的状态在4.3.1.1中。:
- 从中提取消息参数 消息字符串并用作键 搜索名为的ResourceBundle ValidationMessages(经常实现 作为属性文件 /ValidationMessages.properties及其 区域设置变体)使用定义的 locale(见下文)。如果属性是 发现,消息参数是 替换为中的属性值 消息字符串。 应用了第1步 递归直到没有替换 执行(即消息参数 value本身可以包含一条消息 参数)即可。
醇>
答案 0 :(得分:0)
好的,我确实深入研究了这一点。 JSR303指定的算法有一个不直观的混乱,什么(道具)是递归可解析的,什么不是。我认为,这主要是由于注释的属性和RB属性的语法差异很大。
所以我创建了自己的MessageInterpolator,您可以在我的仓库中找到它:http://github.com/Andrey-Sisoyev/adv-msg-interpolator。它解决了几乎所有问题,并且还允许寻找资源包,在哪里寻找属性。