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。它解決了幾乎所有的問題,並且還允許解決資源束在哪裏尋找屬性。