Seam中的JSF表單驗證

梧桐雨—168發表於2008-04-19

在普通JSF中,驗證在檢視中定義:

Country:
Zip code:

在實踐中,這種方式常常違背了DRY原則,因為很多“validation”實際上依賴的約束是資料模型的一部分,而且也有很多方法引入資料庫Schema定義。 Seam使用Hibernate Validator來提供對基於model的約束支援。

讓我們從定義 Location 類的約束開始:

public class Location {
    private String country;
    private String zip;

    @NotNull
    @Length(max=30)
    public String getCountry() { return country; }
    public void setCountry(String c) { country = c; }

    @NotNull
    @Length(max=6)
    @Pattern("^\d*$")
    public String getZip() { return zip; }
    public void setZip(String z) { zip = z; }
}

好,這是一個不錯的切入點,但在實踐中使用自定義的約束可能比 Hibernate Validator 更優雅:

public class Location {
    private String country;
    private String zip;

    @NotNull
    @Country
    public String getCountry() { return country; }
    public void setCountry(String c) { country = c; }

    @NotNull
    @ZipCode
    public String getZip() { return zip; }
    public void setZip(String z) { zip = z; }
}

無論我們使用哪種方式,都不需要在JSF頁面中指定驗證型別。我們可以使用 來驗證定義在model物件上的約束。

Country:
Zip code:

注意: 在model上指定 @NotNull 並不能 在控制上省去 required="true"! 這是因為JSF驗證架構的限制。

這種方式在model中 定義 約束,然後在表現層中 展示 約束違例 — 這顯然是一種更好的設計。

但是,這並不比我們之前的方法簡便多少,所以讓我們試試

Country:
Zip code:

這個標籤只是簡單地給表單中的每個輸入框增加 標籤。 對於一個大的表單來說,這能夠減少很多打字工作量!

現在我們需要做些事情來顯示驗證失敗時的反饋訊息。當前我們是在表單的上方顯示所有訊息。 而我們真正想要做的是在值域後面顯示錯誤的提示訊息(普通JSF也可以實現),高亮顯示欄位和標籤(普通JSF無法實現), 更好的是在欄位後面顯示一些圖片(普通JSF同樣無法實現)。 我們還希望在每個必須輸入的欄位所對應的標記前顯示一個有顏色的*號。

這的確給表單中的每個欄位增加了不少功能。 我們不希望給表單中的每一個欄位指定圖片、訊息和輸入欄位的高亮顯示和佈局。所以我們將通用佈局定義在facelets模板中。



    

我們可以通過 讓每一個表單欄位都使用這個模板。

Country: Zip code:

最後,我們可以使用 RichFaces Ajax 來在使用者瀏覽表單時顯示驗證訊息:

Country: Zip code:

最好為頁面上的重要控制元件定義顯式的id,特別是當你希望用像 Selenium 這樣的工具來進行UI自動化測試時。 如果你沒有提供顯式的id,JSF會生成它們,但任何頁面上的改動都會導致生成的值發生變化。



    

    
        Country:
        
            
        
    

    
        Zip code:
        
            
        
    

    

但是,如果你想在驗證失敗時指定去顯示不同的訊息又該怎麼做呢?可以使用Seam對Hibernate Validator的訊息繫結: (同樣也包括其中那些類似el表示式和獨立檢視訊息繫結之類的各種好處)

public class Location {
    private String name;
    private String zip;

    // Getters and setters for name

    @NotNull
    @Length(max=6)
    @ZipCode(message="#{messages['location.zipCode.invalid']}")
    public String getZip() { return zip; }
    public void setZip(String z) { zip = z; }

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/13270562/viewspace-244093/,如需轉載,請註明出處,否則將追究法律責任。

相關文章