先补充一下上一篇留下的尾巴:最早看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集合生成选项。