JSF 页面导航
导航规则是 JSF 框架提供的那些规则,用于描述单击按钮或链接时要显示的视图。
导航规则可以在名为 faces-config.xml 的 JSF 配置文件中定义。它们可以在托管 bean 中定义。
导航规则可以包含显示结果视图所依据的条件。 JSF 2.0 也提供了隐式导航,无需定义导航规则。
隐式导航
JSF 2.0 提供名为
隐式导航的
自动视图页面解析器机制。在这种情况下,您只需将视图名称放在 action 属性中,JSF 就会在部署的应用程序中自动搜索正确的
视图页面。
JSF 页面中的自动导航
在任何 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 在当前目录中。
托管 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 在当前目录中。
条件导航
使用托管 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";
}
}
}
在 JSF UI 组件中将 pageId 作为请求参数传递。
<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>
这里,当点击"Page1"按钮时。
JSF 将创建一个参数 pageId = 1 的请求
然后JSF会将此参数传递给navigationController的托管属性pageId
现在调用 navigationController.showPage() ,它会在检查 pageId 后将视图返回为 page1
JSF 会将视图名称 page1 解析为 page1.xhtml 扩展名
在当前目录找到对应的视图文件page1.xhtml
基于 from-action 解析导航
JSF 提供导航解析选项,即使托管 bean 的不同方法返回相同的视图名称。
在托管 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 和 from-action 在 faces-config 是 navigationController.processPage1
在当前目录找到对应的视图文件page1.xhtml
转发与重定向
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按钮时,您将得到以下结果。
这里当点击
Redirect下的
Page1按钮时,您将得到以下结果。
示例应用
让我们创建一个测试 JSF 应用程序来测试上述所有导航示例。
步骤 |
描述 |
1 |
在包 com.tutorialspoint.test 下创建一个名为 helloworld 的项目,如JSF-创建应用程序 章节所述。 |
2 |
在包 com.tutorialspoint.test 下创建 NavigationController.java,如下所述。 |
3 |
在 WEB-INF 文件夹下创建 faces-config.xml 并更新其内容,如下所述。 |
4 |
更新 WEB-INF 文件夹下的 web.xml,如下所述。 |
5 |
创建 page1.xhtml 和 page2.xhtml 并修改 home.xhtml 在 webapp 文件夹下,如解释下面。 |
6 |
编译并运行应用程序以确保业务逻辑按照要求工作。 |
7 |
最后,以war文件的形式构建应用,并部署到Apache Tomcat Webserver中。 |
8 |
使用适当的 URL 启动您的 Web 应用程序,如下面最后一步所述。 |
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-创建应用程序一章中一样编译和运行应用程序。如果您的应用程序一切正常,这将产生以下结果。
