JSR 303自定义约束覆盖

时间:2011-12-06 06:35:12

标签: java validation bean-validation

我想在字段上放置一组标准约束(比如非空字母数字字符串,长度从3到240个字符)(在这种情况下是字符串),并想知道是否有办法覆盖某些约束型号代码。对于覆盖的注释,这也是一个重写,或者只是两次验证?

它应该是这样的

@AlphanumericString
@Size(min=100, max=150) //override standart values from AlphanumericString annotation

谢谢你的回答

好的,回答我自己。 @OverridesParameter有助于重新分配嵌套的注释参数

@Numerical
@Size //arbitrary parameter values
@ConstraintValidator(FrenchZipcodeValidator.class)
@Documented
@Target({ANNOTATION_TYPE, METHOD, FIELD})
@Retention(RUNTIME)
public @interface FrenchZipCode {
    String message() default "Wrong zipcode";
    String[] groups() default {};

    @OverridesParameters( {
        @OverridesParameter(constraint=Size.class, parameter="min")
        @OverridesParameter(constraint=Size.class, parameter="max") } )
    int size() default 5;

    @OverridesParameter(constraint=Size.class, parameter="message")
    String sizeMessage() default "{error.zipcode.size}";

    @OverridesParameter(constraint=Numerical.class, parameter="message")
    String numericalMessage() default "{error.zipcode.numerical}";
}

source

1 个答案:

答案 0 :(得分:5)

这是一个很好的问题。 JSR 303 Bean Validation specification描述了3.5节中的验证例程。

  

对于要验证的给定组,验证例程应用于   给定的bean实例应该执行以下约束   验证没有特别的顺序:

     
      
  • 对于所有可到达的字段,执行与目标匹配的所有字段级验证(包括在超类上表示的验证)   除非给定的验证约束已经存在   在给定导航路径的验证例程期间处理   (参见第3.5.1节)作为前一组比赛的一部分。
  •   
     

...

     

对象验证例程如此描述。对于每一个   约束声明:

     
      
  • 确定约束声明,使用适当的ConstraintValidator(参见第3.5.3节)。
  •   
  • 对相应的数据执行isValid操作(来自约束验证实现)(参见第2.4节)
  •   
  • 如果isValid返回true,则继续执行下一个约束,
  •   
  • 如果isValid返回false,则Bean Validation提供程序将根据第2.4节中定义的规则填充ConstraintViolation对象,并将这些对象附加到约束违规列表中。
  •   

在您的情况下,您需要处理目标群组为String的简单Default字段的验证。您有两个验证约束(@AlphanumericString和@Size),根据文档,这些约束将按照特定顺序单独验证/处理。

所以回答你的问题。不,当您再次使用@AlphanumericString时,@Size不会应用任何覆盖。为了能够实现我认为您尝试做的事情,您可以创建一个约束组合,其中您可以通过编写注释来覆盖属性:

@Pattern(regexp="[a-zA-Z]*")
@Size
@Constraint(validatedBy = AlphanumericStringValidator.class)
@Documented
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
@Retention(RUNTIME)
public @interface AlphanumericString {
   // ...
  @OverridesAttribute(constraint=Size.class, name="min")
  int min() default 3
  @OverridesAttribute(constraint=Size.class, name="max")
  int max() default 230;       
   // ...
}

并使用它:

@AlphanumericString(min = 100, max = 150)