JSR 303中的GroupSequence和有序评估

时间:2011-03-12 19:56:09

标签: validation spring-mvc bean-validation

在我们的申请中,我们有这样的情况:

  • 应按特定顺序评估约束。 (便宜到昂贵)
  • 每个字段违规后不应评估约束。
  • 应验证所有字段。

对于前两个,groupsequence非常合适。但是对于我的第三个要求,我找不到解决方法。

public class AccountBean {

   @CheepValidation
   @ExpensiveValidation
   @VeryExpensiveValidation
   private String name;

   @CheepValidation
   @ExpensiveValidation
   @VeryExpensiveValidation
   private String surname
}

例如,

让我们说,对于名称字段,违反了VeryExpensiveValidationconstraint,并且违反了姓氏字段ExpensiveValidation约束。

对于这种情况,我应该显示:

对于字段名称:仅出现VeryExpensiveValidation错误消息 对于字段姓氏:仅ExpensiveValidation错误消息

请注意,对于字段姓氏,我们没有评估VeryExpensiveValidation约束。

有没有办法用JSR 303实现它?

由于

2 个答案:

答案 0 :(得分:3)

你可以使用群组和@GroupSequence,但它有点笨拙。

public class AccountBean {

   @CheapValidation(groups=Name1.class)
   @ExpensiveValidation(groups=Name2.class)
   @VeryExpensiveValidation(groups=Name3.class)
   String name;

   @CheapValidation(groups=Surname1.class)
   @ExpensiveValidation(groups=Surname2.class)
   @VeryExpensiveValidation(groups=Surname3.class)
   String surname;

   public interface Name1 {}
   public interface Name2 {}
   public interface Name3 {}
   @GroupSequence({Name1.class, Name2.class, Name3.class})
   public interface Name {}

   public interface Surname1 {}
   public interface Surname2 {}
   public interface Surname3 {}
   @GroupSequence({Surname1.class, Surname2.class, Surname3.class})
   public interface Surname {}
}

然后验证:

validator.validate(myAccountBean,
    AccountBean.Name.class, AccountBean.Surname.class)

关键是要有两个完全独立的组序列。

不幸的是,您似乎必须明确列出要验证的所有字段的组。我无法使用'默认'@GroupSequence。任何人都可以改进吗?

答案 1 :(得分:0)

我已经使用GroupSequence实现了有序验证,但一般来说,GroupSequence bean验证实现并不透明。

含义,直到第一组完全验证,你不能触发第二组的验证。

E.g。

我有3个带有自定义验证器的验证字段。这个想法很简单:每个字段都应该独立地从上到下验证一组验证器(降序基数)。

        @StringPropertyNotNullOrEmptyConstraint(message = "Group name is required", groups = {ValidationStep1.class})        
        private final StringProperty groupName;    

        @StringPropertyNotNullOrEmptyConstraint(message = "Group password is required", groups = {ValidationStep1.class})
        @StringPropertyMatchConstraint(message = "The given password phrases do not match", dependentProperties = {"groupPasswordMatch"}, groups = {ValidationStep2.class})
        private final StringProperty groupPassword;      

        @StringPropertyNotNullOrEmptyConstraint(message = "Group password match is required", groups = {ValidationStep1.class})
        @StringPropertyMatchConstraint(message = "The given passwords phrases do not match", dependentProperties = {"groupPassword"}, groups = {ValidationStep2.class})    
        private final StringProperty groupPasswordMatch;


        public interface ValidationStep1 {    
        }

        public interface ValidationStep2 {    
        }

        @GroupSequence({GroupDialogModel.class, ValidationStep1.class, ValidationStep2.class})
        public interface GroupDialogModelValidationSequence {    
        }

        ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
        Validator validator = validatorFactory.getValidator();    

        Set<ConstraintViolation<GroupDialogModel>> constraintViolations = validator.validate(this, GroupDialogModelValidationSequence.class);

这种方法的警告是每个字段应首先通过ValidationStep1,并且只有在步骤1的每次验证成功后才进入步骤2.例如,即使密码字段不为空,但包含不同的值,验证为如果组名字段不包含任何值,则它们会成功。只有在我为组名输入一些值后,ValidationStep1组才会成功,然后显示ValidationStep2的验证结果(密码不匹配)。

在每个序列中为每个字段制作每个组是不好的做法恕我直言,但似乎没有其他选择。

非常感谢任何其他解决方案。

相关问题