先補充一下上一篇留下的尾巴:最早看JSF的書的時候,使用jsp作為頁面,#{xx}這樣的標記不能直接寫在頁面里,必須套在一個標記里面(和struts2里面的ognl一樣郁悶)。后來才知道,這是jsp的問題,不是JSF的問題。現在大家都是用facelets作JSF的展現,JSF2.0更是把這個標準化為首選。于是直接在頁面上寫#{someAction.doSth('Hello')},完全OK,頁面加載的時候會觸發調用該方法。

然后我們再來看后端知道前端有什么的例子:


<h:form>
    <h:selectOneMenu value="#{someAction.choise}">
        <f:selectItem itemLabel="a" itemValue="123"/>
        <f:selectItem itemLabel="b" itemValue="456"/>

    </h:selectOneMenu>
</h:form>


上面的代碼最后到客戶端是一個下拉框,客戶選擇某一個選項,最后表單提交的時候,所選值被設置到someAction的choise屬性上。可以嘗試用firebug或者其他的瀏覽器工具在客戶端自己添加一個option,給一個原本沒有的值,然后提交。你會發現JSF會發現提交的值不再備選列表中,于是拋出異常。JSF的頁面是組件化的,后端程序在運行過程中能夠知道前端頁面上有些什么東西,于是可以自動的去校驗。


校驗是一個很典型的例子,但在此之外,知道前端的狀態還有很多其他的妙用。例如當一個表單提交的時候,你可以很輕易的知道一個輸入框的原始值。



JSF1本身對于下拉框的選項的處理是比較惡心的,當你后臺action里面有一個集合,想要依據這個集合生成選項的時候,會遇到一些麻煩。好在seam解決了這個問題,所以同樣參考之后可以實現如下效果:

<h:form>
    <h:selectOneMenu value="#{someAction.choise}">
        <jsf:selectItems value="#{someAction.options}" var="o" label="#{o}"/>
    </h:selectOneMenu>
</h:form>


這里根據someAction里面的choise集合生成選項。