有什麼辦法,我可以這樣做:有沒有辦法在@Size中綁定運行時值?
setValue(@Size(max = Config.getMax()) List<?> aParam);
至於我記得,值需要在編譯時提供。我有一個要求,讓客戶設置這個最大值的值。
這隻能通過自定義驗證/約束來完成嗎?
有什麼辦法,我可以這樣做:有沒有辦法在@Size中綁定運行時值?
setValue(@Size(max = Config.getMax()) List<?> aParam);
至於我記得,值需要在編譯時提供。我有一個要求,讓客戶設置這個最大值的值。
這隻能通過自定義驗證/約束來完成嗎?
正如你所說,約束參數需要在編譯時指定。所以你暗示你的問題是不可能的。
要走的路是使用XML配置。可以通過客戶特定的約束映射文件爲每個客戶配置約束配置。在這種情況下,您可以完全忽略約束註釋,或者添加合理的默認值,在這種情況下,約束映射XML文件需要將ignoreAnnotations標誌設置爲false。
你說得對,約束參數需要在編譯時指定。您將需要一個自定義驗證器。
但我想分享一種解決方案,這是一種介於兩者之間,並且非常靈活。你可以在約束中提供恆定的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();
}
}