说我有以下简单的java bean:
class MyBean {
private Date startDate;
private Date endDate;
//setter, getters etc...
}
JSR 303中是否有一种机制来创建一个自定义验证器来验证startDate必须在endDate之前的约束?
在我看来,这是一个常见的用例,但我找不到这种多属性关系约束的任何例子。
答案 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来扩展它。但我不确定你是否可以修改/覆盖相应的工厂。