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

2022-09-01 22:37:42

假设我有以下简单的java豆:

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

JSR 303 中是否有一种机制来创建自定义验证器来验证 startDate 必须在 endDate 之前的约束?

在我看来,这是一个常见的用例,但我找不到这种多重财产关系约束的任何例子。


答案 1

我可以想出一些事情来尝试。

您可以使用适当的验证程序创建具有类型本身的目标的 a: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;
  }

答案 2

如果您在版本 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;

    //...
}

推荐