2009-11-09 54 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; 

    //... 
} 
相關問題