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

时间:2009-11-09 10:46:25

标签: java validation bean-validation

说我有以下简单的java bean:

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

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

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

5 个答案:

答案 0 :(得分:28)

我可以想到一些事情要尝试。

您可以使用适当的验证器创建一个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;
  }

答案 1 :(得分:10)

如果您在4.1或更高版本中使用Hibernate Validator,则可以使用@ScriptAssert约束以及脚本或表达式语言来表达此类约束。使用JavaScript,您的示例如下所示:

 @ScriptAssert(lang = "javascript", script = "_this.startDate.before(_this.endDate)")
 public class CalendarEvent {

      private Date startDate;

      private Date endDate;

      //...
 } 

对于您选择的脚本语言,您可以通过creating a custom constraint获得更紧凑的语法:

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

    private Date startDate;

    private Date endDate;

    //...
}

答案 2 :(得分:3)

答案是班级验证员。您可以定义可以放置在实体类上的自定义约束。在验证时,您将整个实例传递给isValid()方法。然后,您可以将两个日期相互比较。另请参阅Hibernate Validator documentation

答案 3 :(得分:1)

答案 4 :(得分:-5)

由于无法在JSR 303验证器中访问bean,因此无法实现。

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