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

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

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

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

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

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

您可以使用适当的validation器创建具有类型本身目标的Constraint

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

您可以在类型中封装日期范围并validation:

 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; } 

如果您在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; //... } 

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

@AssertMethodAsTrue – 跨多个属性的可重用约束注释。

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

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