- 浏览: 42134 次
- 性别:
- 来自: 武汉
文章分类
最新评论
17.3 Struts 2整合JSF
目前基于JSF规范较成熟的框架有两个,一个Sun的JSFUI,另一个是Apache的MyFaces框 架。因为Struts 2提供了对MyFaces更好的插件支持,因此本示例采用Apache的MyFaces。整合之前让我们先来比较一下这两种表示层的框架。
17.3.1 Struts 2整合JSF的优点
下面从不同方面比较一下Sturts 2与JSF各自的特点。
首先,在标签库方面,Struts 2的标签库相对要少一些,且不可以自定义;而JSF可以自定义标签。JSF框架拥有丰富的页面组件,如果需要的话可以自己编写相应的组件,或者 扩展组件;而在JSP的页面中JSF提供了页面验证标签,可以做简单的长度和类型的验证。Struts 2的验证可以有两种方式,form验证与validator验证,功能上要比JSF强大。JSF的组件都是绑定到Bean的,而且数据验证的方法也可以绑 定,这一点可以增强验证的功能。而对于验证的错误提示信息,它们都提供了国际化,使得验证更人性化。
其次比较一下导航,二者之间的导航功能的相同点是都通过在XML文件中配置导航规则。Struts 2的XML中配置页面跳转的类型,如转发,重 定向,由Action返回的字符串来决定导航的目标;而JSF在导航规则中设定页面导航,当某个页面请求到来时,根据导航规则调用指定的Action方法进行处理,并返回一个逻辑视图,然后跳转到与逻辑视图对应的页面。JSF同时支持在页面中绑定按钮触发Action的具体方法,导航原理也是一样的。
最后比较一下Struts 2与JSF处理请求的方式。Struts 2调用指定的方法处理请求(如果没有指定具体方法则默认调用excute方法)。JSF采用了普通的POJO类作为它的Action,将Action类绑定到页面组件,通过值变监听与事件监听进行请求处理。相比之下,JSF处理请求的方式要比Struts2复杂,不方便系统升级。
总而言之,如果将JSF做为Struts 2的视图层,用Struts 2的Action做模型,可以开发出完美的应用系统。
接下来就将讲解Struts 2与JSF 的结合使用。
17.3.2 Struts 2与JSF整合过程
每种框架都有它独到的设计之处,Struts 2的可扩展性使得它的生命力非常顽强。Struts 2提供了多种框架的插件包,它与MyFaces 整合就是利用插件来实现的。下面我们介绍如何进行二者的结合应用。
首先下载Struts 2的JSF插件,下载地址是 http://struts.apache.org/ downloads.html。目前最高的插件版本是2.0.11,我们使用这个最新的版本与myfaces进行整合。
Apache的MyFaces下载地址是http://myfaces.apache.org. /download.html,目前的最高版本是1.2.2,本示例使用的是1.1.5。下载后得到名为myfaces-core-1.1.5的压缩文 件,将该文件解压,得到lib包下的运行库文件(.jar文件)。
17.3.3 整合应用实例
2008年是奥运年,因此我们采用目前最流行的奥运啦啦队员的选拔活动为主题,设计一个Struts 2+JSF应用的示例。
奥运啦啦队员选拔队员的设计分为3种功能:增加选手、查询选手、修改选手。
按如下的顺序创建示例程序。
(1)配置环境:配置Struts 2+JSF整合过程的运行环境。
(2)配置struts.xml文件:配置JSF拦截器与请求的Action。
(3)创建页面:注册选手页面,显示所有选手列表页面,修改选手页面。
(4)创建JavaBean。选手信息类PlayerInfo与控制器类OlympicAction。
(5)配置Web应用文件:配置Struts 2请求转发控制器。
(6)发布运行:演示发布运行后的结果页面。
下面详细介绍各个环节的实现过程。
(1)配置应用程序运行环境。
添加Struts 2核心资源包、Struts 2的JSF 插件包、MyFaces资源包。
(2)配置struts.xml。
利用Struts 2+JSF开发视图层,需要的配置文 件是struts.xml。这个文件配置信息分为两个部分,一个是JSF 拦截器的配置,另一个是Struts 2的Action配置。
首先看一下JSF拦截器的配置:
在struts.xml文件中需要配置JSF的拦截器,使得所有的JSF的请求都能被正确处理。这个拦截器在Struts的插件包中已经定义好了,继承这个包就可以使 用这些拦截器。拦截器的配置如代码17-17所示。
代码17-17 struts.xml中JSF拦截器的配置
<!-- 重写拦截器,将其命名在包myJSF中 -->
<package name="myJSF" extends="JSF-default">
<interceptors>
<interceptor-stack name="JSFFullStack">
<interceptor-ref name="params" />
<interceptor-ref name="basicStack" />
<interceptor-ref name="JSFStack" />
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="JSFFullStack" />
</package>
接下来配置请 求的Action。
在请求的Action配置中需要继承myJSF拦截器,用来处理JSF页面的组件。
本应用中来自页面的请求共有4种,如下所示。
l welcome.action:请求显示欢迎页面。配置的 result类型为JSF,使用JSF解析welcome.jsp页面中的组件。
l view.action:请求显示所有选手列表。配置的result类型为JSF,使用JSF解析view.jsp页面中的组件,显示所有已报名选手的列 表信息。
l register.action:请求增加选手。配置两种result。
result的name=“JSF”,使用JSF解析register.jsp页面中的组件。
result 的name=“view”、type类型为chain,即增加选手后直接请求显示所有选手类表的view.action。
l findone.aciton:请求显示修改选手信息
result类型为“JSF”,使用JSF解析 findone.jsp页面中的组件。
result 的name=“view”、type类型为“chain”,即修改选手后直接请求显示所有选手类表的view.action。
struts.xml的详细配置,如代码17-18所示。
代码17-18 struts.xml的详细配置
<!--定义我们的Action的包,并且要继承myJSF -->
<package name="olympic" extends="myJSF">
<!--首次进入的欢迎页面-->
<action name="welcome">
<result type="JSF"/>
</action>
<!--显示所有选手-->
<action name="view" class="com.sunyang.olympic.OlympicAction">
<result name="success" type="JSF" />
</action>
<!--选手报名-->
<action name="register" class="com.sunyang.olympic.OlympicAction">
<result name="success" type="JSF" />
<result name="view" type="redirect">view.action</result>
</action>
<!--修改信息-->
<action name="findone" class="com.sunyang.olympic.OlympicAction" method="findone">
<result name="success" type="JSF" />
<result name="view" type="redirect">view.action</result>
</action>
</package>
(3)创建页面。
示例程序共设计4个页面,分述如下。
l welcome.jsp。欢迎页面。该页面显示两种链接:“我现在就要报名”链接到新增加选手页面;“我想看看都谁报名了”链接到查看所有选手列表信息页 面。
l register.jsp。增加用户页面。单击欢迎页面的“我现在就要报名”,跳转到本页面。该页面显示增加选手的信息,页面使用JSF输入组件标签,表 单提供用户编号、姓名、年龄、性别与联络方式,所有的信息都由选手填写,而且实现数据验证功能,对于不合法的数据类型同时提供错误信息。
l view.jsp。查看所有选手列表信息。该页面采用JSF制表标签,循环遍历显示所有选手信息。该页面还提供了另一个链接“这里还没有我”,单击该链接 跳转到增加选手页面。
l findone..jsp。该页面用来提供选手修改个人信息。
单击查 看所有选手列表信息页面的选手编号,跳转到本页面。本页面采用JSF输入类标签,显示该选手编号对应的详细信息,如选手编号、选手姓名、性 别、年龄及联系方式,供选手修改。修改后单击“我确定修改”,跳转到显示所有选手类表页面。
①欢迎页面welcome.jsp,如代码17-19所示。
代码17-19 welcome.jsp
<%@ page language="java" import="java.util.*" pageEncoding="GBK"%>
<%@ taglib prefix="f" uri="http://java.sun.com/JSF/core" %>
<%@ taglib prefix="h" uri="http://java.sun.com/JSF/html" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'welcome.jsp' starting page</title>
</head>
<body>
<f:view>
<h3>奥运啦啦队员海选报名啦!!!</h3>
<h3>请选择:</h3>
<h:outputLink value="register.action">
<h:outputText value="我现在就要报名!!!" />
</h:outputLink>
<h:outputLink value="view.action">
<h:outputText value="我想看看都谁报名了!!!" />
</h:outputLink>
</f:view>
</body>
</html>
②增加选手的注册页面register.jsp。
单击“我现在就要报名”跳转到注册页面,这个页面的代码很多,标签中的“value”值就是配置在Action中注入的 player的各种属性值,如代码17-20所示。
代码17-20 register.jsp
<%@ page language="java" contentType="text/html; charset=GBK"%>
<%@ taglib prefix="f" uri="http://java.sun.com/JSF/core" %>
<%@ taglib prefix="h" uri="http://java.sun.com/JSF/html" %>
<html>
<head>
<title>注册信息</title>
</head>
<body>
<f:view>
<h3>同一个世界,同一个梦想</h3>
<h3>感谢您对奥运的支持,请填写下列信息......</h3>
<h:form>
<h:panelGrid columns="3">
<h:outputText value="选手编号" />
<h:inputText id="id" size="30" value="#{action.player.id}" required="true" />
<h:message for="id" />
<h:outputText value="选手姓名" />
<h:inputText id="name" size="30" value="#{action.player.name}"
required="true">
<f:validateLength minimum="2" maximum="100" />
</h:inputText>
<h:message for="name" />
<h:outputText value="选手性别" />
<h:inputText id="sex" size="30" value="#{action.player.sex}" required="true">
<f:validateLength minimum="1" maximum="6" />
</h:inputText>
<h:message for="sex" />
<h:outputText value="选手年龄" />
<h:inputText id="age" size="30" value="#{action.player.age}" required="true">
<f:validateLength minimum="1" maximum="100" />
</h:inputText>
<h:message for="age" />
<h:outputText value="联系方式" />
<h:inputText id="tel" size="30" value="#{action.player.tel}" required="true">
<f:validateLength minimum="2" maximum="13" />
</h:inputText>
<h:message for="tel" />
</h:panelGrid>
<h:commandButton value="报名了" action="#{action.save}" />
<br/>
</h:form>
</f:view>
</body>
</html>
③查看所有选手信息列表页面view.jsp。
在注册选手页面,填写选手信息后,单击“报名了”跳转到查看所有选手的页面,该页面将所有选手信息遍历显示到 表格中。标签<h:dataTable>用来显示表格,<f:facet>用来显示表头,<h:column>用来 显示表列,详细的设计如代码17-21所示。
代码17-21 view.jsp
<%@ page language="java" contentType="text/html; charset=GBK"%>
<%@ taglib prefix="f" uri="http://java.sun.com/JSF/core" %>
<%@ taglib prefix="h" uri="http://java.sun.com/JSF/html" %>
<html>
<head>
<title>查看所有选手报名信息</title>
</head>
<body>
<f:view>
<h3>已经有这么多人报名了!!!!!</h3>
<h3>这里有我吗?没有请单击加入他们</h3>
<h:dataTable value="#{action.select}" var="p" style="text-align:center;width:500px"
border="1">
<h:column>
<f:facet name="header">
<h:outputText value="选手编号" />
</f:facet>
<h:outputLink value="findone.action">
<f:param name="playerid" value="#{p.id}" />
<h:outputText value="#{p.id}" />
</h:outputLink>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="选手姓名" />
</f:facet>
<h:outputText value="#{p.name}" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="选手性别" />
</f:facet>
<h:outputText value="#{p.sex}" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="选手年龄" />
</f:facet>
<h:outputText value="#{p.age}" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="联系方式" />
</f:facet>
<h:outputText value="#{p.tel}" />
</h:column>
</h:dataTable>
<p>
<h:outputLink value="register.action">
<h:outputText value="这里还没有我!!" />
</h:outputLink>
</p>
</f:view>
</body>
</html>
④修改选手页面findone.jsp。
单击查看显示所有选手列表页面中的选手编号,跳转到修改选手信息页 面。
在findone.jsp中需要增加一个<h:inputHidden>标签用来隐式的标识“playerid”。将选手编号为“playerid”的属性值显示到页面中。最后提交action的modify方法,详细的设计如 代码17-22所示。
代码17-22 findone.jsp
<%@ page language="java" contentType="text/html; charset=GBK"%>
<%@ taglib prefix="f" uri="http://java.sun.com/JSF/core" %>
<%@ taglib prefix="h" uri="http://java.sun.com/JSF/html" %>
<html>
<head>
<title>修改信息</title>
</head>
<body>
<f:view>
<h3>同一个世界,同一个梦想</h3>
<h3>感谢您对奥运的支持,请修改下列信息>>></h3>
<h:form>
<h:inputHidden value="#{action.playerid}"/>
<h:panelGrid columns="3">
<h:outputText value="选手编号" />
<h:inputText id="id" size="30" value="#{action.player.id}" required="true" />
<h:message for="id" />
<h:outputText value="选手姓名" />
<h:inputText id="name" size="30" value="#{action.player.name}" required="true">
<f:validateLength minimum="2" maximum="100" />
</h:inputText>
<h:message for="name" />
<h:outputText value="选手性别" />
<h:inputText id="sex" size="30" value="#{action.player.sex}" required="true">
<f:validateLength minimum="2" maximum="6" />
</h:inputText>
<h:message for="sex" />
<h:outputText value="选手年龄" />
<h:inputText id="age" size="30" value="#{action.player.age}"
required="true">
<f:validateLength minimum="1" maximum="100" />
</h:inputText>
<h:message for="age" />
<h:outputText value="联系方式" />
<h:inputText id="tel" size="30" value="#{action.player.tel}" required="true">
<f:validateLength minimum="2" maximum="13" />
</h:inputText>
<h:message for="tel" />
</h:panelGrid>
<h3>感谢您对奥运的支持,提交前请确认您的信息</h3>
<h:commandButton value="我确定修改!!!" id="modifyCommand" action=
"#{action.modify}" />
<br/>
</h:form>
</f:view>
</body>
</html>
(4)创建JavaBean,包括选手信息类PlayerInfo与控制器类OlympicAction。
①首先创建选手信息类PlayerInfo.java。
该类中定义选手的各种属性,包括id(编号)、name(名称)、age(年龄)、sex(性别)、 tel(联系方式),如代码17-23所示。
代码17-23 PlayerInfo.java
package com.sunyang.olympic;
public class PlayerInfo {
private int id;
private String name;
private int age;
private String sex;
private int tel;
//定义默认的构造函数
public PlayerInfo(){}
//重写构造函数
public PlayerInfo(int id,String name,String sex,int age,int tel){
this.id=id;
this.name=name;
this.sex=sex;
this.age=age;
this.tel=tel;
}
//省略属性的getter和setter方法
}
②然后创建控制器类OlympicAction.java。
OlympicAction.java用 来处理增加选手页面、修改选手页面、 显示所有选手列表页面、修改选手信息页面功能的各种请求。该类需要继承ActionSupport,注入选手信息类PlayerInfo对象。添 加处理页面表单的方法如下。
l 预存储数据:本应用没有持久化,因此 这里采用预先填写3条数据,存储在List对象中。
l 增加选手:单击增加选手页面中的“报名了”,触发该方法。本应用中的所有选手信息,除了预先存储的数据以外,新增加的选手数据,均存储在会话 session当中。
l 查询所有选手:单击“我想看看都谁报名了”或是在修改选手页面中更新选手信息后,单击“我确定修改!”时触发此方法,此方法调用存储在List中的数据, 如果会话已经被创建,就返回会话当中的列表List;否则返回预先存储的列表List。
l 查找单个选手:该方法根据页面表单中选手的编号,遍历会话session中存储的选手对象,并将该对象中的数据返回给修改选手信息页面,供选手修改。
l 修改选手信息:当选手在修改信息页面中更新当前信息后, 点击“我确定修改!”提交到本方法。 此方法将根据提交的选手编号,更新存 储在会话session中的对象信息,并跳转到查看所有选手信息列表页面。
具体如代码17-24所示。
代码17-24 OlympicAction.java
package com.sunyang.olympic;
public class OlympicAction extends ActionSupport {
// 注入选手POJO
private PlayerInfo player;
// 实例化选手对象
public OlympicAction(){
player=new PlayerInfo(); }
// 定义选手的id属性,用来接受页面值信息
private int playerid;
// 省略他们的getter和setter
//定义封装选手对象的list
List <PlayerInfo> list=new ArrayList<PlayerInfo>();
// 硬性地存储3条数据,
public List<PlayerInfo> setValue(){
// 定义会话session
HttpSession session = ServletActionContext.getRequest().getSession();
if(session.getAttribute("player")==null){
PlayerInfo no1=new PlayerInfo(2008,"Andy","man",25,1111111111);
PlayerInfo no2=new PlayerInfo(2009,"Lily","female",25,22222222);
PlayerInfo no3=new PlayerInfo(2010,"Kaka","man",25,1111111111);
list.add(no1);
list.add(no2);
list.add(no3);
session.setAttribute("player", list);
}
list=(List)session.getAttribute("player");
return list;
}
// 遍历所有的选手并将其传值到页面
public List<PlayerInfo> getSelect(){
List listValue=new ArrayList();
listValue=setValue();
return list;
}
// 增加选手对象
public String save(){
HttpSession session = ServletActionContext.getRequest().getSession();
if(session!=null){
list=setValue();
list.add(player);
session.setAttribute("player",list);
}
return "view";
}
// 遍历单个选手,并将其值传到页面
public String findone(){
HttpSession session = ServletActionContext.getRequest().getSession();
if(session!=null){
list=(List)session.getAttribute("player");
for(int i=0;i<list.size();i++){
PlayerInfo p=list.get(i);
if(p.getId()==playerid){
this.player=p;
}
}
}
return "success";
}
// 用来修改选手信息
public String modify(){
HttpSession session = ServletActionContext.getRequest().getSession();
if(session!=null){
list=(List)session.getAttribute("player");
for(int i=0;i<list.size();i++){
PlayerInfo p=list.get(i);
if(p.getId()==player.getId()){
list.remove(p);
list.add(player);
}
}
}
return "view";
}
}
(5)配置Web应用文件。
Struts 2中使用的JSF的UI标签、JavaBean的绑定功能,都需要使用JSF的Servlet来处理。因此在Web应用文件中需要配置的JSFSevlet处理.action的所有请求,同时要配置 Struts 2的请求转发。如代码17-25所示。
代码17-25 web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="JSF" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<filter>
<filter-name>struts</filter-name>
<filter-class>org.apache.Struts 2.dispatcher.FilterDispatcher</filter-class>
</filter>
<filter-mapping>
<filter-name>struts</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.apache.myfaces.webapp.StartupServletContextListener</listener-class>
</listener>
<!--JSF的servlet -->
<servlet>
<servlet-name>faces</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!--配置所有的.action的请求都有JSF的servlet处理 -->
<servlet-mapping>
<servlet-name>faces</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
</web-app>
(6)最后发布运行。
单击“我想看看都谁报名了”后,进入到查看所有队员信息的页面。
单击欢迎页面的“我现在就要表名!!!”或者页面的“这里还没有我”后进入到增加新的啦啦队 选手的页面。
当单击“报名了”后,跳转到查看所有选手信息的页面。
单击选手编号,可以修改选手的各项信息。
单击“我确定修改!!!”按钮后跳转到查看所有选手页面。
至此,Struts 2和 JSF的整合就完成了,发布运行后,得到预期的效果。但要注意的是,示例中我们将值存储在session会话中,并 没有被真正的持久化,如果要想将数据持久化,就需要增 加持久层及业务层相应代码,这些操作可以参考其它整合持久化框架的章节。
目前基于JSF规范较成熟的框架有两个,一个Sun的JSFUI,另一个是Apache的MyFaces框 架。因为Struts 2提供了对MyFaces更好的插件支持,因此本示例采用Apache的MyFaces。整合之前让我们先来比较一下这两种表示层的框架。
17.3.1 Struts 2整合JSF的优点
下面从不同方面比较一下Sturts 2与JSF各自的特点。
首先,在标签库方面,Struts 2的标签库相对要少一些,且不可以自定义;而JSF可以自定义标签。JSF框架拥有丰富的页面组件,如果需要的话可以自己编写相应的组件,或者 扩展组件;而在JSP的页面中JSF提供了页面验证标签,可以做简单的长度和类型的验证。Struts 2的验证可以有两种方式,form验证与validator验证,功能上要比JSF强大。JSF的组件都是绑定到Bean的,而且数据验证的方法也可以绑 定,这一点可以增强验证的功能。而对于验证的错误提示信息,它们都提供了国际化,使得验证更人性化。
其次比较一下导航,二者之间的导航功能的相同点是都通过在XML文件中配置导航规则。Struts 2的XML中配置页面跳转的类型,如转发,重 定向,由Action返回的字符串来决定导航的目标;而JSF在导航规则中设定页面导航,当某个页面请求到来时,根据导航规则调用指定的Action方法进行处理,并返回一个逻辑视图,然后跳转到与逻辑视图对应的页面。JSF同时支持在页面中绑定按钮触发Action的具体方法,导航原理也是一样的。
最后比较一下Struts 2与JSF处理请求的方式。Struts 2调用指定的方法处理请求(如果没有指定具体方法则默认调用excute方法)。JSF采用了普通的POJO类作为它的Action,将Action类绑定到页面组件,通过值变监听与事件监听进行请求处理。相比之下,JSF处理请求的方式要比Struts2复杂,不方便系统升级。
总而言之,如果将JSF做为Struts 2的视图层,用Struts 2的Action做模型,可以开发出完美的应用系统。
接下来就将讲解Struts 2与JSF 的结合使用。
17.3.2 Struts 2与JSF整合过程
每种框架都有它独到的设计之处,Struts 2的可扩展性使得它的生命力非常顽强。Struts 2提供了多种框架的插件包,它与MyFaces 整合就是利用插件来实现的。下面我们介绍如何进行二者的结合应用。
首先下载Struts 2的JSF插件,下载地址是 http://struts.apache.org/ downloads.html。目前最高的插件版本是2.0.11,我们使用这个最新的版本与myfaces进行整合。
Apache的MyFaces下载地址是http://myfaces.apache.org. /download.html,目前的最高版本是1.2.2,本示例使用的是1.1.5。下载后得到名为myfaces-core-1.1.5的压缩文 件,将该文件解压,得到lib包下的运行库文件(.jar文件)。
17.3.3 整合应用实例
2008年是奥运年,因此我们采用目前最流行的奥运啦啦队员的选拔活动为主题,设计一个Struts 2+JSF应用的示例。
奥运啦啦队员选拔队员的设计分为3种功能:增加选手、查询选手、修改选手。
按如下的顺序创建示例程序。
(1)配置环境:配置Struts 2+JSF整合过程的运行环境。
(2)配置struts.xml文件:配置JSF拦截器与请求的Action。
(3)创建页面:注册选手页面,显示所有选手列表页面,修改选手页面。
(4)创建JavaBean。选手信息类PlayerInfo与控制器类OlympicAction。
(5)配置Web应用文件:配置Struts 2请求转发控制器。
(6)发布运行:演示发布运行后的结果页面。
下面详细介绍各个环节的实现过程。
(1)配置应用程序运行环境。
添加Struts 2核心资源包、Struts 2的JSF 插件包、MyFaces资源包。
(2)配置struts.xml。
利用Struts 2+JSF开发视图层,需要的配置文 件是struts.xml。这个文件配置信息分为两个部分,一个是JSF 拦截器的配置,另一个是Struts 2的Action配置。
首先看一下JSF拦截器的配置:
在struts.xml文件中需要配置JSF的拦截器,使得所有的JSF的请求都能被正确处理。这个拦截器在Struts的插件包中已经定义好了,继承这个包就可以使 用这些拦截器。拦截器的配置如代码17-17所示。
代码17-17 struts.xml中JSF拦截器的配置
<!-- 重写拦截器,将其命名在包myJSF中 -->
<package name="myJSF" extends="JSF-default">
<interceptors>
<interceptor-stack name="JSFFullStack">
<interceptor-ref name="params" />
<interceptor-ref name="basicStack" />
<interceptor-ref name="JSFStack" />
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="JSFFullStack" />
</package>
接下来配置请 求的Action。
在请求的Action配置中需要继承myJSF拦截器,用来处理JSF页面的组件。
本应用中来自页面的请求共有4种,如下所示。
l welcome.action:请求显示欢迎页面。配置的 result类型为JSF,使用JSF解析welcome.jsp页面中的组件。
l view.action:请求显示所有选手列表。配置的result类型为JSF,使用JSF解析view.jsp页面中的组件,显示所有已报名选手的列 表信息。
l register.action:请求增加选手。配置两种result。
result的name=“JSF”,使用JSF解析register.jsp页面中的组件。
result 的name=“view”、type类型为chain,即增加选手后直接请求显示所有选手类表的view.action。
l findone.aciton:请求显示修改选手信息
result类型为“JSF”,使用JSF解析 findone.jsp页面中的组件。
result 的name=“view”、type类型为“chain”,即修改选手后直接请求显示所有选手类表的view.action。
struts.xml的详细配置,如代码17-18所示。
代码17-18 struts.xml的详细配置
<!--定义我们的Action的包,并且要继承myJSF -->
<package name="olympic" extends="myJSF">
<!--首次进入的欢迎页面-->
<action name="welcome">
<result type="JSF"/>
</action>
<!--显示所有选手-->
<action name="view" class="com.sunyang.olympic.OlympicAction">
<result name="success" type="JSF" />
</action>
<!--选手报名-->
<action name="register" class="com.sunyang.olympic.OlympicAction">
<result name="success" type="JSF" />
<result name="view" type="redirect">view.action</result>
</action>
<!--修改信息-->
<action name="findone" class="com.sunyang.olympic.OlympicAction" method="findone">
<result name="success" type="JSF" />
<result name="view" type="redirect">view.action</result>
</action>
</package>
(3)创建页面。
示例程序共设计4个页面,分述如下。
l welcome.jsp。欢迎页面。该页面显示两种链接:“我现在就要报名”链接到新增加选手页面;“我想看看都谁报名了”链接到查看所有选手列表信息页 面。
l register.jsp。增加用户页面。单击欢迎页面的“我现在就要报名”,跳转到本页面。该页面显示增加选手的信息,页面使用JSF输入组件标签,表 单提供用户编号、姓名、年龄、性别与联络方式,所有的信息都由选手填写,而且实现数据验证功能,对于不合法的数据类型同时提供错误信息。
l view.jsp。查看所有选手列表信息。该页面采用JSF制表标签,循环遍历显示所有选手信息。该页面还提供了另一个链接“这里还没有我”,单击该链接 跳转到增加选手页面。
l findone..jsp。该页面用来提供选手修改个人信息。
单击查 看所有选手列表信息页面的选手编号,跳转到本页面。本页面采用JSF输入类标签,显示该选手编号对应的详细信息,如选手编号、选手姓名、性 别、年龄及联系方式,供选手修改。修改后单击“我确定修改”,跳转到显示所有选手类表页面。
①欢迎页面welcome.jsp,如代码17-19所示。
代码17-19 welcome.jsp
<%@ page language="java" import="java.util.*" pageEncoding="GBK"%>
<%@ taglib prefix="f" uri="http://java.sun.com/JSF/core" %>
<%@ taglib prefix="h" uri="http://java.sun.com/JSF/html" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'welcome.jsp' starting page</title>
</head>
<body>
<f:view>
<h3>奥运啦啦队员海选报名啦!!!</h3>
<h3>请选择:</h3>
<h:outputLink value="register.action">
<h:outputText value="我现在就要报名!!!" />
</h:outputLink>
<h:outputLink value="view.action">
<h:outputText value="我想看看都谁报名了!!!" />
</h:outputLink>
</f:view>
</body>
</html>
②增加选手的注册页面register.jsp。
单击“我现在就要报名”跳转到注册页面,这个页面的代码很多,标签中的“value”值就是配置在Action中注入的 player的各种属性值,如代码17-20所示。
代码17-20 register.jsp
<%@ page language="java" contentType="text/html; charset=GBK"%>
<%@ taglib prefix="f" uri="http://java.sun.com/JSF/core" %>
<%@ taglib prefix="h" uri="http://java.sun.com/JSF/html" %>
<html>
<head>
<title>注册信息</title>
</head>
<body>
<f:view>
<h3>同一个世界,同一个梦想</h3>
<h3>感谢您对奥运的支持,请填写下列信息......</h3>
<h:form>
<h:panelGrid columns="3">
<h:outputText value="选手编号" />
<h:inputText id="id" size="30" value="#{action.player.id}" required="true" />
<h:message for="id" />
<h:outputText value="选手姓名" />
<h:inputText id="name" size="30" value="#{action.player.name}"
required="true">
<f:validateLength minimum="2" maximum="100" />
</h:inputText>
<h:message for="name" />
<h:outputText value="选手性别" />
<h:inputText id="sex" size="30" value="#{action.player.sex}" required="true">
<f:validateLength minimum="1" maximum="6" />
</h:inputText>
<h:message for="sex" />
<h:outputText value="选手年龄" />
<h:inputText id="age" size="30" value="#{action.player.age}" required="true">
<f:validateLength minimum="1" maximum="100" />
</h:inputText>
<h:message for="age" />
<h:outputText value="联系方式" />
<h:inputText id="tel" size="30" value="#{action.player.tel}" required="true">
<f:validateLength minimum="2" maximum="13" />
</h:inputText>
<h:message for="tel" />
</h:panelGrid>
<h:commandButton value="报名了" action="#{action.save}" />
<br/>
</h:form>
</f:view>
</body>
</html>
③查看所有选手信息列表页面view.jsp。
在注册选手页面,填写选手信息后,单击“报名了”跳转到查看所有选手的页面,该页面将所有选手信息遍历显示到 表格中。标签<h:dataTable>用来显示表格,<f:facet>用来显示表头,<h:column>用来 显示表列,详细的设计如代码17-21所示。
代码17-21 view.jsp
<%@ page language="java" contentType="text/html; charset=GBK"%>
<%@ taglib prefix="f" uri="http://java.sun.com/JSF/core" %>
<%@ taglib prefix="h" uri="http://java.sun.com/JSF/html" %>
<html>
<head>
<title>查看所有选手报名信息</title>
</head>
<body>
<f:view>
<h3>已经有这么多人报名了!!!!!</h3>
<h3>这里有我吗?没有请单击加入他们</h3>
<h:dataTable value="#{action.select}" var="p" style="text-align:center;width:500px"
border="1">
<h:column>
<f:facet name="header">
<h:outputText value="选手编号" />
</f:facet>
<h:outputLink value="findone.action">
<f:param name="playerid" value="#{p.id}" />
<h:outputText value="#{p.id}" />
</h:outputLink>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="选手姓名" />
</f:facet>
<h:outputText value="#{p.name}" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="选手性别" />
</f:facet>
<h:outputText value="#{p.sex}" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="选手年龄" />
</f:facet>
<h:outputText value="#{p.age}" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="联系方式" />
</f:facet>
<h:outputText value="#{p.tel}" />
</h:column>
</h:dataTable>
<p>
<h:outputLink value="register.action">
<h:outputText value="这里还没有我!!" />
</h:outputLink>
</p>
</f:view>
</body>
</html>
④修改选手页面findone.jsp。
单击查看显示所有选手列表页面中的选手编号,跳转到修改选手信息页 面。
在findone.jsp中需要增加一个<h:inputHidden>标签用来隐式的标识“playerid”。将选手编号为“playerid”的属性值显示到页面中。最后提交action的modify方法,详细的设计如 代码17-22所示。
代码17-22 findone.jsp
<%@ page language="java" contentType="text/html; charset=GBK"%>
<%@ taglib prefix="f" uri="http://java.sun.com/JSF/core" %>
<%@ taglib prefix="h" uri="http://java.sun.com/JSF/html" %>
<html>
<head>
<title>修改信息</title>
</head>
<body>
<f:view>
<h3>同一个世界,同一个梦想</h3>
<h3>感谢您对奥运的支持,请修改下列信息>>></h3>
<h:form>
<h:inputHidden value="#{action.playerid}"/>
<h:panelGrid columns="3">
<h:outputText value="选手编号" />
<h:inputText id="id" size="30" value="#{action.player.id}" required="true" />
<h:message for="id" />
<h:outputText value="选手姓名" />
<h:inputText id="name" size="30" value="#{action.player.name}" required="true">
<f:validateLength minimum="2" maximum="100" />
</h:inputText>
<h:message for="name" />
<h:outputText value="选手性别" />
<h:inputText id="sex" size="30" value="#{action.player.sex}" required="true">
<f:validateLength minimum="2" maximum="6" />
</h:inputText>
<h:message for="sex" />
<h:outputText value="选手年龄" />
<h:inputText id="age" size="30" value="#{action.player.age}"
required="true">
<f:validateLength minimum="1" maximum="100" />
</h:inputText>
<h:message for="age" />
<h:outputText value="联系方式" />
<h:inputText id="tel" size="30" value="#{action.player.tel}" required="true">
<f:validateLength minimum="2" maximum="13" />
</h:inputText>
<h:message for="tel" />
</h:panelGrid>
<h3>感谢您对奥运的支持,提交前请确认您的信息</h3>
<h:commandButton value="我确定修改!!!" id="modifyCommand" action=
"#{action.modify}" />
<br/>
</h:form>
</f:view>
</body>
</html>
(4)创建JavaBean,包括选手信息类PlayerInfo与控制器类OlympicAction。
①首先创建选手信息类PlayerInfo.java。
该类中定义选手的各种属性,包括id(编号)、name(名称)、age(年龄)、sex(性别)、 tel(联系方式),如代码17-23所示。
代码17-23 PlayerInfo.java
package com.sunyang.olympic;
public class PlayerInfo {
private int id;
private String name;
private int age;
private String sex;
private int tel;
//定义默认的构造函数
public PlayerInfo(){}
//重写构造函数
public PlayerInfo(int id,String name,String sex,int age,int tel){
this.id=id;
this.name=name;
this.sex=sex;
this.age=age;
this.tel=tel;
}
//省略属性的getter和setter方法
}
②然后创建控制器类OlympicAction.java。
OlympicAction.java用 来处理增加选手页面、修改选手页面、 显示所有选手列表页面、修改选手信息页面功能的各种请求。该类需要继承ActionSupport,注入选手信息类PlayerInfo对象。添 加处理页面表单的方法如下。
l 预存储数据:本应用没有持久化,因此 这里采用预先填写3条数据,存储在List对象中。
l 增加选手:单击增加选手页面中的“报名了”,触发该方法。本应用中的所有选手信息,除了预先存储的数据以外,新增加的选手数据,均存储在会话 session当中。
l 查询所有选手:单击“我想看看都谁报名了”或是在修改选手页面中更新选手信息后,单击“我确定修改!”时触发此方法,此方法调用存储在List中的数据, 如果会话已经被创建,就返回会话当中的列表List;否则返回预先存储的列表List。
l 查找单个选手:该方法根据页面表单中选手的编号,遍历会话session中存储的选手对象,并将该对象中的数据返回给修改选手信息页面,供选手修改。
l 修改选手信息:当选手在修改信息页面中更新当前信息后, 点击“我确定修改!”提交到本方法。 此方法将根据提交的选手编号,更新存 储在会话session中的对象信息,并跳转到查看所有选手信息列表页面。
具体如代码17-24所示。
代码17-24 OlympicAction.java
package com.sunyang.olympic;
public class OlympicAction extends ActionSupport {
// 注入选手POJO
private PlayerInfo player;
// 实例化选手对象
public OlympicAction(){
player=new PlayerInfo(); }
// 定义选手的id属性,用来接受页面值信息
private int playerid;
// 省略他们的getter和setter
//定义封装选手对象的list
List <PlayerInfo> list=new ArrayList<PlayerInfo>();
// 硬性地存储3条数据,
public List<PlayerInfo> setValue(){
// 定义会话session
HttpSession session = ServletActionContext.getRequest().getSession();
if(session.getAttribute("player")==null){
PlayerInfo no1=new PlayerInfo(2008,"Andy","man",25,1111111111);
PlayerInfo no2=new PlayerInfo(2009,"Lily","female",25,22222222);
PlayerInfo no3=new PlayerInfo(2010,"Kaka","man",25,1111111111);
list.add(no1);
list.add(no2);
list.add(no3);
session.setAttribute("player", list);
}
list=(List)session.getAttribute("player");
return list;
}
// 遍历所有的选手并将其传值到页面
public List<PlayerInfo> getSelect(){
List listValue=new ArrayList();
listValue=setValue();
return list;
}
// 增加选手对象
public String save(){
HttpSession session = ServletActionContext.getRequest().getSession();
if(session!=null){
list=setValue();
list.add(player);
session.setAttribute("player",list);
}
return "view";
}
// 遍历单个选手,并将其值传到页面
public String findone(){
HttpSession session = ServletActionContext.getRequest().getSession();
if(session!=null){
list=(List)session.getAttribute("player");
for(int i=0;i<list.size();i++){
PlayerInfo p=list.get(i);
if(p.getId()==playerid){
this.player=p;
}
}
}
return "success";
}
// 用来修改选手信息
public String modify(){
HttpSession session = ServletActionContext.getRequest().getSession();
if(session!=null){
list=(List)session.getAttribute("player");
for(int i=0;i<list.size();i++){
PlayerInfo p=list.get(i);
if(p.getId()==player.getId()){
list.remove(p);
list.add(player);
}
}
}
return "view";
}
}
(5)配置Web应用文件。
Struts 2中使用的JSF的UI标签、JavaBean的绑定功能,都需要使用JSF的Servlet来处理。因此在Web应用文件中需要配置的JSFSevlet处理.action的所有请求,同时要配置 Struts 2的请求转发。如代码17-25所示。
代码17-25 web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="JSF" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<filter>
<filter-name>struts</filter-name>
<filter-class>org.apache.Struts 2.dispatcher.FilterDispatcher</filter-class>
</filter>
<filter-mapping>
<filter-name>struts</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.apache.myfaces.webapp.StartupServletContextListener</listener-class>
</listener>
<!--JSF的servlet -->
<servlet>
<servlet-name>faces</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!--配置所有的.action的请求都有JSF的servlet处理 -->
<servlet-mapping>
<servlet-name>faces</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
</web-app>
(6)最后发布运行。
单击“我想看看都谁报名了”后,进入到查看所有队员信息的页面。
单击欢迎页面的“我现在就要表名!!!”或者页面的“这里还没有我”后进入到增加新的啦啦队 选手的页面。
当单击“报名了”后,跳转到查看所有选手信息的页面。
单击选手编号,可以修改选手的各项信息。
单击“我确定修改!!!”按钮后跳转到查看所有选手页面。
至此,Struts 2和 JSF的整合就完成了,发布运行后,得到预期的效果。但要注意的是,示例中我们将值存储在session会话中,并 没有被真正的持久化,如果要想将数据持久化,就需要增 加持久层及业务层相应代码,这些操作可以参考其它整合持久化框架的章节。
发表评论
-
Struts2解决表单重复提交
2010-05-29 10:38 1123双击制御 有些时候一些操作会非常的耗费时间(Long Live ... -
Struts2中整合JSF
2010-05-18 16:54 21521,JSF简介 JSF是Sun公司提 ... -
J2EE MVC模式JSF与Struts的异同
2010-05-18 16:45 964Struts和JSF/Tapestry都属于表现层框架,这两种 ... -
Struts2解决表单重复提交
2010-05-18 11:04 1002双击制御 有些时候一些操作会非常的耗费时间(Long Live ... -
struts2 strus.xml中result类型及含义
2010-05-18 11:02 910struts2 strus.xml中result类型及含义 ...
相关推荐
### Struts 2核心技术与Java EE框架整合开发 #### Struts 2框架概览 - **定义**:Struts 2是Apache Software Foundation组织开发的一个开源的Web应用框架,它是Struts 1.x的后续版本,继承和发展了Struts 1的优秀...
在这个实战教程中,作者李刚聚焦于Struts 2、Spring和Hibernate这三个核心组件的整合,它们是Java EE领域中非常流行的开源框架,用于构建现代化的Web应用程序。 Struts 2是一个强大的MVC(模型-视图-控制器)框架,...
【轻量级Java_EE企业应用实战_Struts2_Spring3_Hibernate整合开发】这个主题主要涉及的是Java EE领域中的三大框架——Struts2、Spring3和Hibernate的集成应用,这是构建现代Java后端系统的一种常见方式。这些框架...
《轻量级Java EE企业应用实战(第4版)》这本书深入探讨了Struts 2、Spring 4和Hibernate这三大框架的整合开发,旨在帮助读者掌握如何在实际项目中高效构建Java EE应用。SSH(Struts 2、Spring、Hibernate)是Java ...
《轻量级Java_EE企业应用实战_Struts_2+Spring_3+Hibernate整合开发_第3版》这本书深入探讨了在Java EE环境下如何利用轻量级框架Struts 2、Spring 3和Hibernate进行高效的企业级应用开发。这三者结合在一起,形成了...
《轻量级Java EE企业应用实战 第3版》是一本深度探讨Java EE开发技术的书籍,专注于Struts 2、Spring 3和Hibernate这三大框架的整合应用。这本书旨在帮助开发者掌握如何在实际项目中有效地集成这三个流行的技术,...
《轻量级Java EE企业应用实战——Struts 2+Spring+Hibernate整合开发电子书1》是一本专注于Java EE企业级应用开发的书籍,主要涵盖了Struts 2、Spring和Hibernate这三个流行开源框架的整合应用。这本书对于Java...
《轻量级Java_EE企业应用实战》一书聚焦于Struts 2、Spring 3和Hibernate这三大框架的整合开发,旨在为读者提供一套高效、实用的企业级应用解决方案。Struts 2作为MVC(模型-视图-控制器)框架,主要负责处理HTTP...
通过学习《轻量级Java EE企业应用开发实战———Struts 2+Spring+Hibernate整合开发》这本书籍和配套的课件,开发者可以深入理解 SSM 框架的原理和实践,掌握企业级应用开发的关键技能。课程中可能涵盖了如何搭建...
介绍了Java EE领域的三个开源框架:Struts 2、Spring和Hibernate。 这是第三部分,我上传的上限是60MB,所以不得不分包额!
《轻量级Java EE企业应用实战(第4版)》是一本深入讲解如何使用Struts 2、Spring 4与Hibernate进行整合开发的专业书籍。该书不仅覆盖了这三种框架的基本概念和技术细节,还通过实战项目的形式,让读者能够在实际...
《轻量级Java EE企业应用实战——Struts 2+Spring+Hibernate整合开发电子书3》是一本专注于Java EE轻量级开发技术的专著,它深入探讨了Struts 2、Spring和Hibernate(SSH)这三大流行开源框架的集成与应用。...
《轻量级Java EE企业应用实战——Struts 2+Spring+Hibernate整合开发》是一本深入探讨Java EE企业级应用开发的书籍,尤其关注于轻量级框架的整合使用。Struts 2、Spring和Hibernate,简称SSH,是Java开发中最流行...
《轻量级Java EE企业应用实战--Struts 2+Spring+Hibernate整合开发》这本书由李刚编著,主要探讨了在Java EE环境下如何利用轻量级框架进行高效的企业级应用开发。书中聚焦于三个核心的开源框架:Struts 2、Spring 和...
《轻量级Java EE企业应用实战:Struts2+Spring3+Hibernate整合开发(第3版)》介绍了Java EE领域的三个开源框架:Struts 2、Spring和Hibernate。其中Struts 2升级到2.2.1,Spring升级到3.0.5,Hibernate升级到了...
《轻量级Java EE企业应用实战:Struts2+Spring3+Hibernate整合开发(第3版)》介绍了Java EE领域的三个开源框架:Struts 2、Spring和Hibernate。其中Struts 2升级到2.2.1,Spring升级到3.0.5,Hibernate升级到了...
《轻量级Java+EE企业应用实战——Struts 2 + Spring + Hibernate整合开发》是针对Java企业级应用开发的一本实战指南,旨在帮助开发者掌握使用Struts 2、Spring和Hibernate三大框架进行高效集成开发的技术与技巧。...
《轻量级Java EE企业应用实战:Struts2+Spring3+Hibernate整合开发(第3版)》介绍了Java EE领域的三个开源框架:Struts 2、Spring和Hibernate。其中Struts 2升级到2.2.1,Spring升级到3.0.5,Hibernate升级到了...
《轻量级Java EE企业应用实战_Struts 2_Spring3_Hibernate(第三版)》是一本深入浅出地介绍如何构建高效、可扩展的企业级应用程序的书籍,它结合了Struts 2、Spring 3和Hibernate这三大流行框架,为Java EE开发者...
总之,《精通Java EE Eclipse Struts2 Hibernate Spring整合应用案例 源代码18章 bookstore》是一份宝贵的教育资源,它提供了一手的实战经验,让开发者能够在实际场景中学习和掌握Java EE开发的核心技术。...