有没有办法在@Size中绑定运行时值?

时间:2015-10-08 10:33:27

标签: java-ee bean-validation

我有什么方法可以做类似的事情:

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

据我记忆,这个值需要在编译时提供。我要求客户设置此最大尺寸的值。

这只能通过自定义验证/约束来完成吗?

2 个答案:

答案 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();
    }
}