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的引用来扩展它。 但我不确定您是否可以修改/覆盖相应的工厂。