2012-01-16 31 views
2

所以,你可以使用上的綁定bean屬性JSR-303註解驗證輸入:驗證JSF中的任意對象?

class Ticket { 
    @MinAge(18) 
    Person person; 
} 

class Person { 
    @Min(1) @Max(100) 
    int age; 
} 

<p:inputText id="age" value="#{bean.ticket.person.age}" /> 

這裏,Person.age驗證(間1..100)沒有問題的性質。

問題是,我想驗證外部實例(person.age> = 18)。但如何使財產bean.ticket.person被驗證?

我想是這樣的:

<p:inputText id="age" value="#{bean.ticket.person.age}"> 
    <f:validate value="#{bean.ticket.person}" /> 
</p:inputText> 

或者:

<p:inputText id="age" value="#{bean.ticket.person.age}"> 
    <f:validator id="jsr303-validator" value="#{bean.ticket.person}" /> 
</p:inputText> 

的問題是,我不能一個值傳遞給<f:validator />。我想爲驗證過程添加額外的屬性,而不僅僅是頁面上出現的輸入。

P.S.這是一個簡化的例子,實際應用是:

... 
<p:inputText id="principalLabel" value="${activeACL.principal.label}" readonly="true" /> 
<p:commandButton value="Choose..." onclick="choosePrincipalDialog.show()" /> 
... 
<p:commandButton value="Save" action="${bean.saveACL}" oncomplete="editACLDialog.hide()" update="index" /> 

和類型ACL_DTO的activeACL:

class ACL_DTO { 
    ... 
    @IdRequired 
    Principal_DTO principal; 
} 

這裏,choosePrincipalDialog的的ActionListener將隱式變更的${activeACL.principal.id},其最初是null。 IdRequired是一個自定義約束,它約束對象的id成員屬性不爲null或-1。

雖然,我可以改變使用@NotNull的id屬性,並添加一個隱藏的輸入,使該ID驗證:

class Principal_DTO { 
    ... 
    @NotNull 
    @Min(0) 
    Long id; 
} 

... 
<h:inputHidden id="principalId" value="${activeACL.principal.id}" /> 
<h:inputText id="principalLabel" ... 

但是,這種方式我不能重用驗證消息。給用戶看起來像「這個字符串不應該爲空」,「這個值不應該是-1」似乎毫無意義。

回答

1

首先,我認爲你應該確保只使用bean作爲你獲得輸入的地方。之後,您將值分配給模型。在我看來,bean不應該直接作爲模型使用,而應該作爲一個Web形式支持bean(每個Web表單都有不同的bean)。其次,我同意你遇到了依賴於其他數據進行驗證的場景(例如,如果用戶選擇美國作爲國家,郵編等不應該留空)。你可以看看這裏如何實現自定義註釋: Cross field validation with Hibernate Validator (JSR 303)

如果你不使用Bean驗證你總是可以實現自定義驗證程序類,甚至直接在bean定義驗證方法:http://docs.oracle.com/javaee/6/tutorial/doc/bnavb.html#bnave