JSF页面导航示例教程
页面导航是基于例如单击按钮或者单击链接时执行的事件的页面重定向。
定义页面导航的方法有很多。
这些包括
- 在提交按钮的操作属性中指定页面名称
- 指示托管bean中的页面
- 在faces-config.xml中指定导航
- 根据条件定义导航
隐式导航(在action属性中指定页面名称)
JSF允许我们在"提交"按钮的action属性中指定页面名称或者视图名称,这将解析带有.xhtml扩展名的页面名称。
考虑下面的示例。
pagenav.xhtml
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="https://www.w3.org/1999/xhtml"
xmlns:h="https://java.sun.com/jsf/html">
<h:head>
<title>Page Navigation</title>
</h:head>
<h:body>
<h3>Page Navigation</h3>
<h:form>
<h:panelGrid columns="3" >
<h:outputLabel for="cname">Car Name:</h:outputLabel>
<h:inputText value="#{car.cname}" id="cname"></h:inputText>
<br <br
<h:outputLabel for="Id">Car Id:</h:outputLabel>
<h:inputText value="#{car.id}"></h:inputText>
<br <br
<h:outputLabel for="color">Color:</h:outputLabel>
<h:inputText value="#{car.color}"></h:inputText>
<br <br
<h:outputLabel for="model">Model:</h:outputLabel>
<h:inputText value="#{car.model}"></h:inputText>
<br <br
<h:outputLabel for="regno">Registration Number:</h:outputLabel>
<h:inputText value="#{car.regno}"></h:inputText>
<br <br
<h:commandButton action="viewdetails" value="Submit"></h:commandButton>
</h:panelGrid>
</h:form>
</h:body>
</html>
其中视图名称viewdetails在commandbutton标签的action属性中指定。
创建" viewdetails.xhtml",其中在单击"提交"按钮后将重定向设置为此页面(目标)
viewdetails.xhtml
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="https://www.w3.org/1999/xhtml"
xmlns:h="https://java.sun.com/jsf/html">
<h:head>
<title>Car Details</title>
</h:head>
<h:body>
Car Id:#{car.id}
<br <br
Car Name:#{car.cname}
<br <br
Car color:#{car.color}
<br <br
Car Model:#{car.model}
<br <br
Car Registration Number:#{car.regno}
</h:body>
</html>
创建一个托管beanCar.java作为
Car.java
package com.theitroad.jsf.beans;
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
@ManagedBean
@SessionScoped
public class Car implements Serializable {
private static final long serialVersionUID = 4672207931321758371L;
private String cname;
private String color;
private String Id;
private String model;
private String regno;
public Car() {
}
public Car(String cname, String color, String Id, String model, String regno) {
this.cname = cname;
this.color = color;
this.Id = Id;
this.model = model;
this.regno = regno;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public String getCname() {
System.out.println("car name is" + cname);
return cname;
}
public void setCname(String cname) {
this.cname = cname;
}
public String getRegno() {
return regno;
}
public void setRegno(String regno) {
this.regno = regno;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public String getId() {
return Id;
}
public void setId(String Id) {
this.Id = Id;
}
public String add() {
return "form";
}
public String view() {
return "form";
}
}
完成这些更改后,运行应用程序。
当用户单击提交按钮时,他将被带到新页面。
通过托管Bean导航
在第二种类型中,我们借助于托管Bean中的方法指定视图页面,并在视图页面中调用托管Bean的该方法。
考虑下面的例子
创建一个托管beanCarBean.java
CarBean.java
package com.theitroad.jsf.beans;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
@ManagedBean
@SessionScoped
public class CarBean {
private String cname;
private String Id;
private String color;
private String model;
private String regno;
private String description;
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public String getCname() {
return cname;
}
public void setCname(String cname) {
this.cname = cname;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getRegno() {
return regno;
}
public void setRegno(String regno) {
this.regno = regno;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public String getId() {
return Id;
}
public void setId(String Id) {
this.Id = Id;
}
public String add() {
return "pagenav";
}
}
其中我们定义方法add,其中我们指定要在单击按钮时呈现的相应视图页面。
创建一个名为managedbeannav.xhtml的视图
managedbeannav.xhtml
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="https://www.w3.org/1999/xhtml"
xmlns:h="https://java.sun.com/jsf/html">
<h:head>
<title>Page Navigation</title>
</h:head>
<h:body>
<h3>Page Navigation using Managed Bean</h3>
<h:form>
<h:commandButton action="#{carBean.add()}" value="Add Car Details"
</h:form>
</h:body>
</html>
单击"添加汽车详细信息"按钮,将渲染" pagenav.xhtml"。
请参考上面在隐式导航中创建的pagenav.xhtmljsf页面。
从car bean中的add方法中,调用pagenav.xhtml页面,在action属性中,我们调用方法add。
这是我们运行应用程序时发生的情况。
在faces-config.xml中导航
在第三种类型中,我们在" faces-config.xml"文件中指定页面。
我们来看一个例子。
我们将重用前面步骤中定义的Car.java bean。
现在,将" car.xhtml"页面创建为
car.xhtml
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="https://www.w3.org/1999/xhtml"
xmlns:h="https://java.sun.com/jsf/html">
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body>
<h3>Navigation through faces-config.xml</h3>
<h:form>
<h:commandLink action="#{car.add}" value="Add Car details "
<br
<br
<h:commandLink action="#{car.view}" value="View Details"
</h:form>
</h:body>
</html>
接下来,创建要在导航期间呈现的视图页面。
view.xhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="https://www.w3.org/1999/xhtml"
xmlns:h="https://java.sun.com/jsf/html">
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body>
Car Id:C1 <br
Car Name:Alto <br
Car color:blue
</h:body>
</html>
pagenav.xhtml将如上面创建的那样重复使用,单击添加链接后将呈现该页面。
现在创建一个新文件" faces-config.xml"以包含导航映射。
这应该放在WEB-INF文件夹中。
faces-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<faces-config xmlns="https://java.sun.com/xml/ns/javaee"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://java.sun.com/xml/ns/javaee
https://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
version="2.0">
<navigation-rule>
<from-view-id>car.xhtml</from-view-id>
<navigation-case>
<from-action>#{car.add}</from-action>
<from-outcome>form</from-outcome>
<to-view-id>pagenav.xhtml</to-view-id>
</navigation-case>
<navigation-case>
<from-action>#{car.view}</from-action>
<from-outcome>form</from-outcome>
<to-view-id>view.xhtml</to-view-id>
</navigation-case>
</navigation-rule>
</faces-config>
我们调用托管beancar.java的add和view方法,这将返回表单字符串。
在faces-config.xml中搜索表单字符串以获取调用方法的名称,然后将该方法名称映射到" pagenav.xhtml"页面以进行渲染。
同样,也呈现了视图页面。
让我们运行该应用程序。
转发与重定向导航
默认情况下,JSF在从一页导航到另一页时提供前向导航,并且浏览器URL不会更改。
要启用页面重定向,请在视图名称的末尾设置" faces-redirect = true"。
我们将看一个解释前进和重定向导航的示例。
创建JSF视图页面forward.xhtml为
forward.xhtml
<?xml version='1.0' encoding='UTF-8' ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="https://www.w3.org/1999/xhtml" xmlns:h="https://java.sun.com/jsf/html"> <h:head> <title>Facelet Title</title> </h:head> <h:body> <h:form> <h3>Forward Navigation</h3> <h:commandButton action="pagenav" value="Add Car Details" <h3>Redirect Navigation</h3> <h:commandButton action="pagenav?faces-redirect=true" value="Add Car Details" </h:form> </h:body> </html>
我们在视图页面名称" pagenav"的末尾设置了" faces-redirect = true"。
这样可确保启用了重定向导航。
请参考上面创建的pagenav.xhtml代码。
现在运行产生以下输出的应用程序。
在上面的屏幕截图中,即使呈现了" add.xhtml"页面,该URL仍显示" forward.xhtml"作为页面名称。
这用于使应用程序更安全和健壮。
在重定向导航中,URL显示在浏览器中呈现的实际当前页面,即" pagenav.xhtml"。
条件导航
在最后一种类型的条件导航中,我们指定应基于哪些条件呈现视图。
让我们考虑一个示例来演示条件导航
创建托管beanCarNav.java,如下所示
CarNav.java
package com.theitroad.jsf.beans;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.RequestScoped;
@ManagedBean(name = "carnav", eager = true)
@RequestScoped
public class CarNav {
@ManagedProperty(value = "#{param.pid}")
private String pid;
public String showPage() {
if (pid == null) {
return "car_nav";
}
if (pid.equals("1")) {
return "pagenav";
} else if (pid.equals("2")) {
return "view";
} else {
return "car_nav";
}
}
public String getPid() {
return pid;
}
public void setPid(String pid) {
this.pid = pid;
}
}
在CarNav bean中,如果pid为1,则呈现pagenav,如果页面id为2,则呈现视图页面。
此条件写在showPage()方法中。
我们将创建car_nav.xhtml页面,该页面接受页面ID作为参数。
car_nav.xhtml
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="https://www.w3.org/1999/xhtml"
xmlns:h="https://java.sun.com/jsf/html"
xmlns:c="https://java.sun.com/jsf/core">
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body>
<h3>Conditional Navigation</h3>
<h:form>
<h:commandLink action="#{carnav.showPage()}" value="Add">
<c:param name="pid" value="1"
</h:commandLink>
<br
<br
<h:commandLink action="#{carnav.showPage()}" value="View">
<c:param name="pid" value="2"
</h:commandLink>
</h:form>
</h:body>
</html>
重用pagenav.xhtml并查看view.xhtmlJSF代码进行导航。

