2015-10-08 119 views
1

有什麼辦法,我可以這樣做:有沒有辦法在@Size中綁定運行時值?

setValue(@Size(max = Config.getMax()) List<?> aParam); 

至於我記得,值需要在編譯時提供。我有一個要求,讓客戶設置這個最大值的值。

這隻能通過自定義驗證/約束來完成嗎?

回答

1

正如你所說,約束參數需要在編譯時指定。所以你暗示你的問題是不可能的。

要走的路是使用XML配置。可以通過客戶特定的約束映射文件爲每個客戶配置約束配置。在這種情況下,您可以完全忽略約束註釋,或者添加合理​​的默認值,在這種情況下,約束映射XML文件需要將ignoreAnnotations標誌設置爲false

0

你說得對,約束參數需要在編譯時指定。您將需要一個自定義驗證器。

但我想分享一種解決方案,這是一種介於兩者之間,並且非常靈活。你可以在約束中提供恆定的EL表達式。因此,您的自定義約束和自定義驗證使用了javax.el-API。要在jsp/jsf之外使用EL,您可以找到一篇不錯的博客文章here

public class myBean { 
    @MySize(max="config.max") 
    private String someData; 
} 

@Target({ElementType.FIELD}) 
@Retention(RetentionPolicy.RUNTIME) 
@Constraint(validatedBy = MySizeValidator.class) 
@Documented 
public @interface MySize { 

    String message() default "size is invalid"; 

    Class<?>[] groups() default {}; 

    Class<? extends Payload>[] payload() default {}; 

    String max(); 
} 

public class MySizeValidator implements ConstraintValidator<MySize, Object> { 
    // See blog entry how to write your own ElContext. Provide a Producer 
    // that binds your referenced beans (e.g. 'config') to the context 
    @Inject 
    private ValidationElContext elContext; 

    private String maxExpression; 

    @Override 
    public void initialize(MySize constraintAnnotation) { 
     super.initialize(); 
     this.maxExpression = constraintAnnotation.max(); 
    } 

    @Override 
    public boolean isValid(Object value, ConstraintValidatorContext context) { 
     if (value==null) return true; 
     int max = evalExpression(maxExpression); 
     return .... // check size of value and compare. 
    } 

    protected int evalExpression(String expression) { 
     ExpressionFactory fac = ExpressionFactory.newInstance(); 
     ValueExpression ve = fac.createValueExpression(elContext, expression, Integer.class); 

     return ((Integer)ve.getValue(elContext)).intValue(); 
    } 
} 
相關問題