導航規則是JSF框架提供的那些規則,用於描述單擊按鈕或連結時要顯示哪個視圖。
導航規則可以在JSF配置文件faces-config.xml中定義。它們可以在託管bean中定義。
導航規則可以包含顯示結果視圖的條件。JSF 2.0還提供了隱式導航,無需定義導航規則。
Implicit Navigation
JSF 2.0提供了名爲隱式導航的自動查看頁面解析器機制。在這種情況下,您只需要將視圖名放在action屬性中,JSF將在部署的應用程式中自動搜索正確的視圖頁面。
Auto Navigation in JSF Page
在任何JSF UI組件的action屬性中設置視圖名。
<h:form> <h3>Using JSF outcome</h3> <h:commandButton action = "page2" value = "Page2" /> </h:form>
在這裡,當點擊Page2按鈕時,JSF將解析視圖名,Page2作爲Page2.xhtml擴展名,並在當前目錄中找到相應的視圖文件Page2.xhtml。
Auto Navigation in Managed Bean
在託管bean中定義方法以返回視圖名稱。
@ManagedBean(name = "navigationController", eager = true) @RequestScoped public class NavigationController implements Serializable { public String moveToPage1() { return "page1"; } }
使用託管bean獲取任何JSF UI組件的action屬性中的視圖名。
<h:form> <h3> Using Managed Bean</h3> <h:commandButton action = "#{navigationController.moveToPage1}" value = "Page1" /glt; </h:form>
在這裡,當點擊Page1按鈕時,JSF將解析視圖名,Page1作爲Page1.xhtml擴展名,並在當前目錄中找到相應的視圖文件Page1.xhtml。
Conditional Navigation
使用託管bean,我們可以很容易地控制導航。查看託管bean中的以下代碼。
@ManagedBean(name = "navigationController", eager = true) @RequestScoped public class NavigationController implements Serializable { //this managed property will read value from request parameter pageId @ManagedProperty(value = "#{param.pageId}") private String pageId; //condional navigation based on pageId //if pageId is 1 show page1.xhtml, //if pageId is 2 show page2.xhtml //else show home.xhtml public String showPage() { if(pageId == null) { return "home"; } if(pageId.equals("1")) { return "page1"; }else if(pageId.equals("2")) { return "page2"; }else { return "home"; } } }
Pass pageId as a request parameter in JSF UI Component.
<h:form> <h:commandLink action = "#{navigationController.showPage}" value = "Page1"> <f:param name = "pageId" value = "1" /> </h:commandLink> <h:commandLink action = "#{navigationController.showPage}" value = "Page2"> <f:param name = "pageId" value = "2" /> </h:commandLink> <h:commandLink action = "#{navigationController.showPage}" value = "Home"> <f:param name = "pageId" value = "3" /> </h:commandLink> </h:form>
Here, when "Page1" button is clicked.
JSF will create a request with parameter pageId = 1
然後JSF將把這個參數傳遞給navigationController的託管屬性pageId
現在調用navigationController.showPage(),它將在檢查pageId之後返回視圖page1
JSF將把視圖名page1解析爲page1.xhtml擴展名
在當前目錄中找到相應的視圖文件page1.xhtml
Resolving Navigation Based on from-action
即使託管bean的不同方法返回相同的視圖名,JSF也提供導航解析選項。
查看託管bean中的以下代碼。
public String processPage1() { return "page"; } public String processPage2() { return "page"; }
要解析視圖,請在faces-config.xml中定義以下導航規則
<navigation-rule> <from-view-id>home.xhtml</from-view-id> <navigation-case> <from-action>#{navigationController.processPage1}</from-action> <from-outcome>page</from-outcome> <to-view-id>page1.jsf</to-view-id> </navigation-case> <navigation-case> <from-action>#{navigationController.processPage2}</from-action> <from-outcome>page</from-outcome> <to-view-id>page2.jsf</to-view-id> </navigation-case> </navigation-rule>
這裡,單擊Page1按鈕時−
調用navigationController.processPage1(),它將以頁的形式返回視圖
JSF將解析視圖名,page1因爲視圖名是page,而從faces config中的action中解析的是navigationController.processPage1
在當前目錄中找到相應的視圖文件page1.xhtml
Forward vs Redirect
默認情況下,JSF在導航到另一個頁面時執行伺服器頁面轉發,應用程式的URL不會更改。
要啓用頁面重定向,請在視圖名稱的末尾附加faces redirect=true。
<h:form> <h3>Forward</h3> <h:commandButton action = "page1" value = "Page1" /> <h3>Redirect</h3> <h:commandButton action = "page1?faces-redirect = true" value = "Page1" /> </h:form>
在這裡,單擊Forward下的Page1按鈕,將得到以下結果。
單擊「重定向」下的「第1頁」按鈕時,將得到以下結果。
Example Application
讓我們創建一個測試JSF應用程式來測試上述所有導航示例。
Step | Description |
---|---|
1 | Create a project with a name helloworld under a package com.tutorialspoint.test as explained in the JSF - Create Application chapter. |
2 | Create NavigationController.java under a package com.tutorialspoint.test as explained below. |
3 | Create faces-config.xml under a WEB-INF folder and updated its contents as explained below. |
4 | Update web.xml under a WEB-INF folder as explained below. |
5 | Create page1.xhtml and page2.xhtml and modify home.xhtml under a webapp folder as explained below. |
6 | Compile and run the application to make sure business logic is working as per the requirements. |
7 | Finally, build the application in the form of war file and deploy it in Apache Tomcat Webserver. |
8 | Launch your web application using appropriate URL as explained below in the last step. |
NavigationController.java
package com.tutorialspoint.test; import java.io.Serializable; import javax.faces.bean.ManagedBean; import javax.faces.bean.ManagedProperty; import javax.faces.bean.RequestScoped; @ManagedBean(name = "navigationController", eager = true) @RequestScoped public class NavigationController implements Serializable { private static final long serialVersionUID = 1L; @ManagedProperty(value = "#{param.pageId}") private String pageId; public String moveToPage1() { return "page1"; } public String moveToPage2() { return "page2"; } public String moveToHomePage() { return "home"; } public String processPage1() { return "page"; } public String processPage2() { return "page"; } public String showPage() { if(pageId == null) { return "home"; } if(pageId.equals("1")) { return "page1"; }else if(pageId.equals("2")) { return "page2"; }else { return "home"; } } public String getPageId() { return pageId; } public void setPageId(String pageId) { this.pageId = pageId; } }
faces-config.xml
<?xml version = "1.0" encoding = "UTF-8"?> <faces-config xmlns = "http://java.sun.com/xml/ns/javaee" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd" version = "2.0"> <navigation-rule> <from-view-id>home.xhtml</from-view-id> <navigation-case> <from-action>#{navigationController.processPage1}</from-action> <from-outcome>page</from-outcome> <to-view-id>page1.jsf</to-view-id> </navigation-case> <navigation-case> <from-action>#{navigationController.processPage2}</from-action> <from-outcome>page</from-outcome> <to-view-id>page2.jsf</to-view-id> </navigation-case> </navigation-rule> </faces-config>
web.xml
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <display-name>Archetype Created Web Application</display-name> <context-param> <param-name>javax.faces.PROJECT_STAGE</param-name> <param-value>Development</param-value> </context-param> <context-param> <param-name>javax.faces.CONFIG_FILES</param-name> <param-value>/WEB-INF/faces-config.xml</param-value> </context-param> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>*.jsf</url-pattern> </servlet-mapping> </web-app>
page1.xhtml
<?xml version = "1.0" encoding = "UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns = "http://www.w3.org/1999/xhtml" xmlns:h = "http://java.sun.com/jsf/html"> <h:body> <h2>This is Page1</h2> <h:form> <h:commandButton action = "home?faces-redirect = true" value = "Back To Home Page" /> </h:form> </h:body> </html>
page2.xhtml
<?xml version = "1.0" encoding = "UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns = "http://www.w3.org/1999/xhtml" xmlns:h = "http://java.sun.com/jsf/html"> <h:body> <h2>This is Page2</h2> <h:form> <h:commandButton action = "home?faces-redirect = true" value = "Back To Home Page" /> </h:form> </h:body> </html>
home.xhtml
<?xml version = "1.0" encoding = "UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns = "http://www.w3.org/1999/xhtml" xmlns:f = "http://java.sun.com/jsf/core" xmlns:h = "http://java.sun.com/jsf/html"> <h:body> <h2>Implicit Navigation</h2> <hr /> <h:form> <h3>Using Managed Bean</h3> <h:commandButton action = "#{navigationController.moveToPage1}" value = "Page1" /> <h3>Using JSF outcome</h3> <h:commandButton action = "page2" value = "Page2" /> </h:form> <br/> <h2>Conditional Navigation</h2> <hr /> <h:form> <h:commandLink action = "#{navigationController.showPage}" value="Page1"> <f:param name = "pageId" value = "1" /> </h:commandLink> <h:commandLink action = "#{navigationController.showPage}" value="Page2"> <f:param name = "pageId" value = "2" /> </h:commandLink> <h:commandLink action = "#{navigationController.showPage}" value = "Home"> <f:param name = "pageId" value = "3" /> </h:commandLink> </h:form> <br/> <h2>"From Action" Navigation</h2> <hr /> <h:form> <h:commandLink action = "#{navigationController.processPage1}" value = "Page1" /> <h:commandLink action = "#{navigationController.processPage2}" value = "Page2" /> </h:form> <br/> <h2>Forward vs Redirection Navigation</h2> <hr /> <h:form> <h3>Forward</h3> <h:commandButton action = "page1" value = "Page1" /> <h3>Redirect</h3> <h:commandButton action = "page1?faces-redirect = true" value = "Page1" /> </h:form> </h:body> </html>
完成所有更改後,讓我們像在JSF-創建應用程式一章中那樣編譯和運行應用程式。如果您的應用程式一切正常,這將產生以下結果。