2.6 导航模型
JSF应用通常总需要在配置文件中定义一组导航规则,当用户单击按钮、超链接时,JSF可以根据这种导航规则转向到其他页面。在页面转向的背后,托管Bean的处理方法会对用户请求进行处理,导航规则可以根据处理结果转向到不同的页面。
JSF使用<navigation-rule…/>配置导航规则,该元素的内部结构如图2.21所示。
图2.21 <navigation-rule…/>元素的内部结构
从图2.21可以看出,在<navigation-rule…/>元素内有如下两个有序的子元素:
<from-view-id…/>:这是一个可选元素,该元素指定导航规则的起始页面。如果没有指定该元素,则意味着该导航规则对起始页面不做限制,表明这个<navigation-rule…/>元素可应用于应用中所有页面,即可从应用中任何页面导航到其他页面。
<from-view-id…/>元素还允许使用通配符,通过使用通配符可以匹配一批起始页面,例如如下配置片段:
<from-view-id>/books/*</from-view-id>
上面配置片段表明/books目录下的任何页面都可作为起始页面。
<navigation-case…/>:该元素可以出现0至多次,JSF将根据该元素的配置决定导航到哪一个视图页面。每个<navigation-case…/>元素配置一个导航规则。
简单来说,一个导航规则就是需要指定:从什么地方来(由<from-view-id…/>指定),到什么地方去(由<navigation-case…/>元素指定)。JSF允许从一个地方来,到多个地方去,因此<navigation-rule…/>元素内可以包含多个<navigation-case…/>元素。
<navigation-case…/>元素不仅需要指定要导航到哪个视图页面,实际上它还可以指定一系列条件,只有满足这些条件时才会导航到目标页面,因此该元素内部还可包含如下子元素:
<from-action…/>:这是一个可选的子元素,该元素的值是一个方法表达式,用于指定某个Bean的特定方法,表明只有由该Bean的特定方法处理用户请求时才会导航到指定页面。
<from-outcome…/>:这是一个可选的子元素,该元素定义了一个逻辑结果(例如“success”、“failure”等字符串),表明当处理方法返回该逻辑结果时才会导航到指定页面。
<to-view-id…/>:该元素指定一个物理视图资源,表明要导航到哪个页面。
<redirect…/>:使用该元素表明采用重定向方式来导航到指定页面,而不是采用常规的ViewHandler机制进行导航。
例如下面配置片段:
<navigation-rule/> <!-- 表明/books路径下任何页面都可作为起始页面 --> <from-view-id>/books/*</from-view-id> <navigation-case> <!-- 表明从bookBean的add方法返回success时 --> <from-action>#{bookBean.add}</ from-action> <from-outcome>success</from-outcome> <!-- 满足上面条件时导航到/show.jsp --> <to-view-id>/show.jsp</to-view-id> </navigation-case> <navigation-case> <!-- 表明从bookBean的delete方法返回success时 --> <from-action>#{bookBean.delete}</ from-action> <from-outcome>success</from-outcome> <!-- 满足上面条件时导航到/deleteResult.jsp --> <to-view-id>/deleteResult.jsp</to-view-id> </navigation-case> </navigation-rule>
上面配置片段配置/books路径下所有页面都可作为起始页面,该路径下所有页面的Action事件触发bookBean的add处理方法返回“success”字符串时,应用导航到/show.jsp页面;该路径下所有页面的Action事件触发bookBean的delete处理方法返回“success”字符串时,应用导航到/deleteResult.jsp页面。
2.6.1 静态导航
静态导航是JSF应用中最简单的一种导航方式,它只要开发者完成如下两件事情即可:
将commandButton或commandLink标签的action属性指定为一个静态字符串。
在JSF配置文件中配置导航规则。
下面的应用示范了一个静态导航的示例。下面页面中commandButton标签的action属性并不是绑定到某个托管Bean的指定方法,而是直接给出一个静态的字符串。页面代码如下:
程序清单:codes\02\2.6\staticNav\WEB-INF\src\org\crazyit\jsf\BookBean.java
<h:form>
<!-- 将下面UI组件的值绑定到Bean属性 -->
书名:<h:inputText value="#{bookBean.name}"/><br/>
<!-- 将下面UI组件本身绑定到Bean属性 -->
价格:<h:inputText value="#{bookBean.price}"/><br/>
<h:commandButton value="处理" action="success"/><br/>
</h:form>
上面页面代码中粗体字代码指定action="success",这意味着单击该按钮时无须触发任何Action方法,它直接返回一个静态的“success”字符串——这意味着无论用户输入什么,单击该按钮总是固定导航到指定页面,至于到底导航到哪个页面,依然取决于导航规则配置文件。
程序清单:codes\02\2.6\staticNav\WEB-INF\faces-config.xml
<navigation-rule>
<!-- 导航规则的输入页面 -->
<from-view-id>/welcome.jsp</from-view-id>
<!-- 如果welcome.jsp中Action方法的处理结果是success,
则跳转到视图页show.jsp -->
<navigation-case>
<from-outcome>success</from-outcome>
<to-view-id>/show.jsp</to-view-id>
</navigation-case>
</navigation-rule>
上面配置文件指定如果以/welcome.jsp作为起始页面,若该页面上commandButton、commandLink触发的Action方法返回值为success,应用导航到/show.jsp页面。
将该应用部署在WebLogic服务器中,不管用户在/welcome.jsp页面中输入什么,应用总是导航到/show.jsp页面。
2.6.2 动态导航
动态导航是JSF应用最常用的导航方式,动态导航也只要开发者完成两件事情即可:
将commandButton或commandLink标签的action属性绑定到某个托管Bean的处理方法。
在JSF配置文件中配置导航规则。
因为动态导航中将commandButton或commandLink标签的action属性绑定到某个托管Bean的Action处理方法,这样就使得当该commandButton或commandLink生成的按钮、超链接被单击时,它所对应的托管Bean的Action处理方法将被调用,该方法可以对用户请求进行处理,根据该Action处理方法的返回值不同,应用可以动态导航到不同的页面。
关于动态导航的示例,本书前面已经介绍了不少例子,故此处不再赘述。