如何设置JSR303 bean验证的检查顺序

时间:2010-09-30 03:34:44

标签: validation bean-validation

我使用JSR303 Bean Validation来检查表单输入。

@NotBlank
@Size(min = 4, max = 30)
private String name;

@NotBlank
@Size(max = 100)
@Email
private String mail;

然后是name =''和email ='',@ NotBlank,名称为@Size,@ NotBlank, @Size,邮件中的@Email将被检查。

我想设置检查顺序,例如,当前一个订单无效时,不检查下一个订单。

@NotBlank(order = 1)
@Size(min = 4, max = 30, order = 2)
private String name;

(上面不支持JSR303)

有没有办法实现它使用JSR303? (我认为自定义注释会完成,但我不想为每个属性添加自定义注释)

我还考虑了验证组和组序列,但我认为我的需求存在一些差异。

@NotBlank(groups = First.class)
@Size(min = 4, max = 30, groups = Second.class)
private String name;

@NotBlank(groups = First.class)
@Size(max = 100, groups = Second.class)
@Email(groups = Third.class)
private String mail;

当名称为空且邮件为“abc”时。 JSR303只会检查名称中的@NotBlank和邮件中的@NotBlank,因为名称上的@NotBlank无效,因此不会检查第二组和第三组。

但我需要的是姓名@NotBlank和@NotBlank,@ Size,邮件@Email应该被检查。由于名称上的@NotBlank无效,因此不会检查名称上的@Size,并且邮件中的@ NotBlank,@ Size是有效的,因此将检查邮件中的@Email。

也许,下面的伪代码将清楚地描述我的要求。

// retrieves all fields and check one by one.
for (Field field : fields) {
  List annotations = getJsr303Annotations(field);
  // retrieves all annotations on field and check one by one.
  for (Annotation annotation : annotations) {
    CheckResult result = check(annotation, field);
    if (result.isValid()) {
       continue;
    } else {
       errors.add(result);
       break;
    }
  }
}

有没有一种方法可以通过JSR303实现我的要求?

3 个答案:

答案 0 :(得分:6)

是Bean验证支持此功能。它被称为验证组和组序列。组是简单的标记接口,例如,您可以创建两个接口 First Second ,并将代码更改为以下内容:

@NotBlank(groups = First.class)
@Size(min = 4, max = 30, groups = Second.class)
private String name;

然后你可以定义一个组序列:

@GroupSequence({ First.class, Second.class})
interface All {
}

抓住验证器并调用validator.validate(myObject,All.class)

这一切都在文档中。

答案 1 :(得分:2)

在撰写此答案时,无法指定验证相关注释/约束的顺序。我前一段时间已向Hibernate Validator团队提交了与订单相关的问题,该问题已被接受,可能会在下一个Bean Validation规范版本中得到解决 - 请参阅此处的详细信息:http://beanvalidation.org/proposals/BVAL-248/顺便说一下,在简单的情况下你可以避免"订购冲突"通过使用"非冲突"注释的组合,例如NotNullSize - 对于null值,大小将评估为真。

答案 2 :(得分:1)

您是否考虑过定义两个序列。一个用于名称,一个用于邮件

@GroupSequence({NameFirst.class, NameSecond.class})
interface AllName {
}

@GroupSequence({MailFirst.class, MailSecond.class, MailThird.class})
interface AllMail {
}

在这种情况下,您可以像这样调用验证器:

validator.validate(myObject, AllName.class, AllMail.class)