Validation jsr303中的GroupSequence和有序求值
在我们的申请中,我们有这样一种情况:Validation jsr303中的GroupSequence和有序求值,validation,spring-mvc,bean-validation,Validation,Spring Mvc,Bean Validation,在我们的申请中,我们有这样一种情况: 应按特定顺序评估约束。(便宜到贵) 每个字段发生冲突后,不应计算约束 应验证所有字段 对于前两个,groupsequence非常适合。然而,对于我的第三个要求,我找不到解决的方法 public class AccountBean { @CheepValidation @ExpensiveValidation @VeryExpensiveValidation private String name; @CheepValid
- 应按特定顺序评估约束。(便宜到贵)
- 每个字段发生冲突后,不应计算约束
- 应验证所有字段
public class AccountBean {
@CheepValidation
@ExpensiveValidation
@VeryExpensiveValidation
private String name;
@CheepValidation
@ExpensiveValidation
@VeryExpensiveValidation
private String surname
}
比如说,
比方说,违反了名称字段VeryExpensiveValidationconstraint,违反了姓氏字段ExpensiveValidation约束
对于这种情况,我应该显示:
对于字段名:仅VeryExpensiveValidation错误消息
字段姓氏:仅ExpensiveValidation错误消息
请注意,对于字段姓氏,我们没有评估VeryExpensiveValidation约束
有没有办法用JSR303实现它
谢谢您可以使用groups和@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)
关键是要有两个完全独立的群序列
不幸的是,似乎必须明确列出要验证的所有字段的组。我无法让它使用'default'@GroupSequence。有人能改进这一点吗?我已经用GroupSequence实现了有序验证,但一般来说,GroupSequence bean验证实现是不透明的 也就是说,在第一组完全验证之前,您不能触发第二组的验证 例如 我有3个带有自定义验证器的已验证字段。这个想法非常简单:每个字段都应该使用一组自上而下独立的验证器进行验证(基数递减)
@StringPropertyNotNullOrEmptyConstraint(message=“需要组名”,groups={ValidationStep1.class})
私有属性组名;
@StringPropertyNotNullOrEmptyConstraint(message=“需要组密码”,groups={ValidationStep1.class})
@StringPropertyMatchConstraint(message=“给定的密码短语不匹配”,dependentProperties={“groupPasswordMatch”},groups={ValidationStep2.class})
私有属性组密码;
@StringPropertyNotNullOrEmptyConstraint(message=“需要组密码匹配”,groups={ValidationStep1.class})
@StringPropertyMatchConstraint(message=“给定密码短语不匹配”,dependentProperties={“groupPassword”},groups={ValidationStep2.class})
私有属性groupPasswordMatch;
公共接口验证步骤1{
}
公共接口验证步骤2{
}
@GroupSequence({GroupDialogModel.class,ValidationStep1.class,ValidationStep2.class})
公共接口GroupDialogModelValidationSequence{
}
ValidatorFactory=Validation.buildDefaultValidatorFactory();
Validator Validator=validatorFactory.getValidator();
Set constraintViolations=validator.validate(这是GroupDialogModelValidationSequence.class);
这种方法的警告是,每个字段都应该首先通过ValidationStep1,只有在步骤1的每次验证成功后,才会进入步骤2。例如,即使密码字段不是空的,但包含不同的值,如果组名字段不包含任何值,验证也会成功。只有在我为组名输入一些值之后,ValidationStep1组才会成功,然后它才会显示ValidationStep2的验证结果(密码不匹配)
在每个序列中为每个领域分组是一种糟糕的做法,但似乎别无选择
非常感谢任何其他解决方案。如果AccountBean.Name出现错误,这是AccountBean.Name之后的validate AccountBean.姓氏吗?我想验证所有字段。@Ozgur,是的,我测试了解决方案,它同时验证了“名称”和“姓氏”。传递给“验证”的组列表不会短路;只有@GroupSequence会导致短路。(对吗?)
@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);