有没有办法在@Size 中绑定运行时值?
Is there any way to bind a runtime value in @Size?
有什么方法可以做类似的事情:
setValue(@Size(max = Config.getMax()) List<?> aParam);
据我所知,该值需要在编译时提供。我有一个要求让客户设置这个最大尺寸的值。
这只能通过自定义来完成吗validation/constraint?
正如你所说,约束参数需要在编译时指定。所以你在问题中暗示的是不可能的。
方法是使用 XML 配置。可以通过客户特定的约束映射文件为每个客户配置约束配置。在这种情况下,您可以完全省略约束注释或添加合理的默认值,在这种情况下,在约束映射 XML 文件中,需要将 ignoreAnnotations 标志设置为 假.
没错,约束参数需要在编译时指定。您将需要一个自定义验证器。
但我想分享一个介于两者之间且非常灵活的解决方案。您可以在约束中提供常量 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();
}
}
有什么方法可以做类似的事情:
setValue(@Size(max = Config.getMax()) List<?> aParam);
据我所知,该值需要在编译时提供。我有一个要求让客户设置这个最大尺寸的值。
这只能通过自定义来完成吗validation/constraint?
正如你所说,约束参数需要在编译时指定。所以你在问题中暗示的是不可能的。
方法是使用 XML 配置。可以通过客户特定的约束映射文件为每个客户配置约束配置。在这种情况下,您可以完全省略约束注释或添加合理的默认值,在这种情况下,在约束映射 XML 文件中,需要将 ignoreAnnotations 标志设置为 假.
没错,约束参数需要在编译时指定。您将需要一个自定义验证器。
但我想分享一个介于两者之间且非常灵活的解决方案。您可以在约束中提供常量 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();
}
}