我有什么方法可以做类似的事情:
setValue(@Size(max = Config.getMax()) List<?> aParam);
据我记忆,这个值需要在编译时提供。我要求客户设置此最大尺寸的值。
这只能通过自定义验证/约束来完成吗?
答案 0 :(得分:1)
正如您所说,需要在编译时指定约束参数。所以你在提问时暗示的是不可能的。
要采用的方法是使用XML配置。可以通过客户特定约束映射文件为每个客户配置约束配置。在这种情况下,您可以完全省略约束注释,或者添加合理的默认值,在这种情况下,在约束映射XML文件中,需要将 ignoreAnnotations 标志设置为 false
答案 1 :(得分: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();
}
}