Java Bean Validation(JSR303)约束涉及多个bean属性之间的关系

23

假设我有以下简单的Java bean:

class MyBean {
   private Date startDate;
   private Date endDate;
   //setter, getters etc...
}

JSR 303有没有机制来创建一个自定义验证器,用于验证开始日期必须在结束日期之前的约束条件?

这似乎是一种常见的用例,但我找不到任何关于这种多属性关系约束的示例。


1
似乎有人在他的博客中发布了一个完整的示例:http://soadev.blogspot.de/2010/01/jsr-303-bean-validation_29.html - Ralph
5个回答

34

我能想到一些尝试的方法。

你可以创建一个目标为类型本身的约束Constraint,并使用适当的验证器:

@ValidateDateRange(start="startDate", end="endDate")
public class MyBean {

你可以将日期范围封装在一个类型中并进行验证:

public class DateRange {    
  private long start;
  private long end;

  public void setStart(Date start) {
    this.start = start.getTime();
  }

  // etc.

您可以添加一个简单的属性来执行检查:

public class MyBean {
  private Date startDate;
  private Date endDate;

  @AssertTrue public boolean isValidRange() {
    // TODO: null checks
    return endDate.compareTo(startDate) >= 0;
  }

14
如果您使用版本4.1或更高版本的Hibernate Validator,则可以使用@ScriptAssert约束与脚本或表达式语言一起使用来表示此类约束。使用JavaScript,您的示例将如下所示:
 @ScriptAssert(lang = "javascript", script = "_this.startDate.before(_this.endDate)")
 public class CalendarEvent {

      private Date startDate;

      private Date endDate;

      //...
 } 

您可以通过为所选脚本语言创建自定义约束条件来获得更紧凑的语法:

@JexlAssert("_.startDate < _.endDate")
public class CalendarEvent {

    private Date startDate;

    private Date endDate;

    //...
}

3
答案是一个类级别的验证器。您可以定义自定义约束,可以将其放置在实体类上。在验证时,整个实例都会传递到isValid()方法中。然后,您可以将两个日期进行比较。另请参阅Hibernate Validator 文档

1

2
虽然这个链接可能回答了问题,但最好在此处包含答案的基本部分并提供参考链接。仅有链接的答案如果链接页面发生更改可能会变得无效。 - gevorg

-5

由于在JSR 303验证器中无法访问bean,因此这是不可能的。

一种解决方法是提供自己的ConstraintValidatorContext并将其扩展为引用当前正在验证的bean。但我不确定您是否可以修改/覆盖相应的工厂。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接