2009-11-09 56 views
21

说我有以下简单的java bean:的Java Bean验证(JSR303),涉及几个bean的属性之间的关系的约束

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

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

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

+1

它接缝,有人张贴在一个完整的例子他博客:http://soadev.blogspot.de/2010/01/jsr-303-bean-validation_29.html – Ralph 2015-07-20 17:27:16

回答

27

我可以考虑几件事情来尝试。

您可以与类型本身的目标与相应的验证创建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; 
    } 
-5

由于无法访问JSR 303验证程序中的bean,因此这是不可能的。

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

3

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

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; 

    //... 
} 
相关问题