0

我已经写了JSR303验证是比较属性值约束: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. 

会有人请建议容易和方便的方式,如何使验证识别并解决嵌套{} home.lang.validator.Cmp.REL.GT关键?我需要它能够很好地用于处理验证的JSF2。 我使用的不是春天,但使用Hibernate验证器4

顺便说一句,看起来像休眠验证器4没有完全实现JSR303,因为后来国家在4.3.1.1:

  1. 消息参数从 消息字符串提取并用作键 搜索名为 ValidationMessages所述的ResourceBundle(通常物化 作为属性文件 /ValidationMessages.properties及其 语言环境的变化)使用所定义的 区域设置(见下文)。如果找到属性 ,则消息参数是 将替换为消息字符串中的属性值 。 递归地应用步骤1 ,直到没有执行替换为 (即,消息参数 值本身可以包含消息 参数)

回答

0

好的,我确实深入了解了这一点。 JSR303指定的算法对于什么(道具)可递归解析和什么是不可解的混淆。我认为,这主要是由于注释的性质和RB的属性在语法上的差别。

所以我制作了自己的MessageInterpolator,可以在我的回购中找到:http://github.com/Andrey-Sisoyev/adv-msg-interpolator。它解决了几乎所有的问题,并且还允许解决资源束在哪里寻找属性。