3

假设有一个这样的bean:

public class Car {
     @ConstraintA      
     @ConstraintB
     private String type;

     //getters and setters
}

通常,需要接受两个约束才能使字段有效。Bean Validation 中是否有可能以某种方式配置,如果ConstraintA有效,则仅检查ConstraintB并且仅当两者都失败时使字段无效?

编辑:更多解释......假设ValidatorA用于ConstraintA,ValidatorB用于ConstraintB。在典型配置中,Bean Validation 的工作方式如下:

if (validatorA.isValid(car.type) && validatorB.isValid(car.type)) {
    validate(car);
}

我想问是否有一种方法可以配置它来做这样的事情:

if (validatorA.isValid(car.type) || validatorB.isValid(car.type)) {
    validate(car);
} 
4

1 回答 1

4

我不确定我得到你的要求,但如果你打算只在没有失败@Contraint2时执行验证,你可以使用groups@Contraint1做这样的事情:JSR-303

@GroupSequence(value={Car.class, Contraint1Group.class,Contraint2Group.class})
public class Car {

  @ContraintA(groups=Contraint1Group.class)
  @ContraintB(groups=Contraint2Group.class)
  private String type;

}

您还需要声明标记接口以指定组:

public interface Contraint1Group extends Default { }

public interface Constraint2Group {}

其中第一个扩展javax.validation.groups.Default是当没有使用约束注释指定组时的默认扩展。


问题更新后编辑:您可以,但前提是使用休眠验证器,虽然它是 JSR-303 的参考实现,但提供@ConstraintComposition(OR)扩展,同时创建新的自定义组合验证规则:

@ConstraintComposition(OR)
@Constraint1
@Constraint2
@ReportAsSingleViolation
@Target({ METHOD, FIELD })
@Retention(RUNTIME)
@Constraint(validatedBy = { })
public @interface Constraint1ORConstraint2 {
   String message() default "{Constraint1ORConstraint2.message}";
   Class<?>[] groups() default { };
   Class<? extends Payload>[] payload() default { };
}

其中@ReportAsSingleViolation意味着每次执行只会报告一次违规(您可以全部删除此注释)。由于@Constraint1ORConstraint2注释本身不需要额外的验证,所以不要在@Constraint元注释中声明验证器。

于 2013-06-05T16:05:29.627 回答