当前位置:文档之家› 第五章 Struts2基础入门 (理论)

第五章 Struts2基础入门 (理论)

第五章   Struts2基础入门 (理论)
第五章   Struts2基础入门 (理论)

第5章

Struts2 基础入门

本章学习内容:

1. Struts2 体系结构

2. Struts2 运行流程

3. Struts2与Struts1的对比

4. Struts2入门示例

5. 跟踪用户状态

6. ValueStack的概念

本章学习目标:

1. 掌握Struts2体系结构

2. 理解Struts2运行流程

3.掌握struts.xml文件的配置

4.能使用Struts2框架开发Web应用程序

5.掌握使用ValueStack存储数据

本章简介:

通过上一章的学习,我们掌握了Struts1框架的HTML标签库、Bean标签库、Logic标签库等知识。但是Struts1框架有天生的设计缺陷,包括:支持的表现层技术单一、与Servlet API严重耦合,难于测试、代码严重依赖于Struts1 API,属于侵入式设计等。为了弥补以上缺陷,Struts2框架应运而生。Struts2的体系与Struts1的体系差别非常大,因为Struts2使用了WebWork的设计核心,而不是使用Struts1的设计核心。Struts2大量使用拦截器来处理用户请求,从而允许用户的业务逻辑控制器彻底与Servlet API分离。Struts2下的控制器不再像Struts1下的控制器,需要继承一个Action父类,甚至可以无需实现任何接口,Struts2的控制器就是一个包含execute方法的普通POJO类。本章主要讲述Struts1存在的问题、Struts2体系结构、运行流程、使用Struts2重构用户登录、Struts2中的valueStack等知识。

5.1Struts2概述

Struts1现在已经发展成为一个高度成熟的框架,不管是稳定性还是可靠性,都得到了广泛的证明。但由于Struts1存在一些设计上的缺陷,于是催生了Struts2框架。Struts2与Struts1相比,确实有很多革命性的改进,但它并不是一个全新的框架,而是在WebWork基础上发展起来。从某种意义上讲,Struts2没有继承Struts1,而是继承了WebWork框架,或者说,WebWork衍生出了Struts2,而不是Struts1衍生了Struts2。

因为Struts2是WebWork的升级,而不是一个全新的框架,因此稳定性和性能各方面都有很好的保证,而且吸收了Struts1和WebWork两者的优势,因此,Struts2是一个非常完善的MVC实现框架。

5.1.1Struts1框架存在的问题

对于Struts1框架而言,因为它与JSP/Servlet紧密耦合,因而导致了许多不可避免的设计缺陷,随着Web应用程序规模的扩大,这些缺陷逐渐变成制约Struts1发展的重要因素,这也是Struts2出现的原因。

下面具体分析Struts1中存在的缺陷。

(1)支持的表现层技术单一

Struts1只支持JSP作为表现层技术,不提供与其它表现层技术,例如Velocity、FreeMarker

等技术的整合。这一点严重制约了Struts1框架的使用,对于目前的很多Java EE应用程序而

言,并不一定使用JSP作为表现层技术。

(2)与Servlet API严重耦合,难于测试

因为Struts1框架是在Model 2的基本上发展起来的,因此它完全是基本Servlet API的,所

以在Struts1的业务逻辑控制器内,充满了大量的Servlet API。分析以下Struts1业务逻辑控

制器代码:

public class LoginAction extends Action

{

public ActionForward execute(ActionMapping mapping,

ActionForm form,

HttpServletRequest request,

HttpServletResponse response) {

. . .

}

}

当我们需要测试上面Action类的execute()方法是,该方法有4个参数:ActionMapping、

ActionForm、HttpServletRequest和HttpServletResponse,初始化这4个参数比较困难。尤其

是HttpServletRequest和HttpServletResponse两个参数,通常由Web容器负责实例化。因此

一旦脱离了Web服务器,Action测试非常困难。

(3)代码严重依赖于Struts1 API,属于侵入式设计

正如从上面代码片段中所看到的,Struts1的Action类必须继承Struts1的基类,实现处理方法

时,又包含了大量Struts1的API:如ActionMapping、ActionForm和ActionForward类。这种

侵入式设计的最大缺点在于,一旦系统需要重构时,这些Action类完全没有利用价值。可见,

Struts1的Action类这种侵入式设计导致了较低的代码利用。

5.1.2Struts2体系结构

Struts2的体系与Struts1的体系差别非常大,因为Struts2使用了WebWork的设计核心,而不是使用Struts1的设计核心。Struts2大量使用拦截器来处理用户请求,从而允许用户的业务逻辑控制器彻

底与Servlet API分离。Struts2的体系结构主要包括Struts2控制器组件、Struts2配置文件和Struts2

标签库等3部分。

1Struts2的控制器组件

Struts2的控制器组件是Struts2框架的核心,事实上,所有MVC框架都是以控制器组件为核心的。

Struts2的控制器由两个部分组成:核心控制器FilterDispathcer和业务控制器Action。

(1)核心控制器:FilterDispathcher

FilterDispatcher是Struts2框架的核心控制器,该控制器作为一个Filter运行在Web应用程序

中,它负责拦截所有的用户请求,当用户请求到达时,该Filter会过滤用户请求。如果用户

请求以action结尾,该请求将被转入Struts2框架处理。Struts2框架获得了*.action请求后,

将根据*.action请求的前面部分决定调用那个业务控制器,例如,对于login.action的请求,

Strtus2调用名为login的Action来处理该请求。

(2)业务控制器

业务控制器Action需由用户自己实现,在配置文件中进行配置,以供核心控制器FilterDispatcher 来使用。实际上,Struts2应用程序起作用的业务控制器不是用户自定义的Action,而是系统生成的

Action的代理,但该Action代理以用户定义的Action为目标。以下是Struts2的Action代码示例:

public class LoginAction

{

//封装用户请求参数的uid属性

private String uid;

//封装用户请求参数的pwd属性

private String pwd;

//处理用户请求的execute方法

public String execute() throws Exception

{

//如果登录成功,则进入主页面

if("scott".equals(this.uid) && "tiger".equals(this.pwd))

{

return "success";

}

//否则进入登录失败错误提示页面

return "fial";

}

//getter、setter方法

public String getPwd() {

return pwd;

}

public void setPwd(String pwd) {

this.pwd = pwd;

}

public String getUid() {

return uid;

}

public void setUid(String uid) {

this.uid = uid;

}

}

以上Action代码无需实现任何父接口,无需继承任何Struts2基类,该Action类完全是一个POJO(普通、传统的Java对象),因此具有很好的复用性。

归纳起来,Struts2的Action类有如下优势:

1.Action类完全是一个POJO类,因此具有很好的代码重用性。

2.Action类无需与任何Servlet API耦合,因此进行单元测试非常简单。

3.Action类的execute方法仅返回一个字符串作为处理结果,该处理结果可映射到任何的视

图,甚至是另一个Action。

2Struts2的配置文件

当Struts2创建系统的Action代理时,需要使用Struts2的配置文件。Struts2的配置文件有两份:

(1)配置Action的struts.xml文件

(2)配置Struts2全局属性的struts.properties文件(可选)

struts.xml文件内定义了Struts2的系列Action,定义Action时,指定该Action的实现类,并定义该Action处理结果与视图资源之间的映射关系。以下是struts.xml配置文件的示例:

/index.jsp

/fail.jsp

在上面的struts.xml文件中,定义了一个Action,定义Action时,不仅定义了Action实现类,而

且通过”name”属性指定访问该Action的逻辑名,此处为“login”。其中”result”元素用于指定

execute方法返回值和视图资源之间的映射关系。对于如下配置片段:

/index.jsp

表示当execute方法返回”success”字符串时,流程将转发至index.jsp页面。

除此之外,Struts2还有一个配置Struts2全局属性的properties文件:struts.properties。该文件的示例如下:

#指定Struts2标签的主题为普通主题

struts.ui.theme=simple

struts.properties文件的形式是一系列的key、value对,它指定了Struts2应用程序的全局属性。

3Struts2标签库

Struts2的标签库提供了非常丰富的功能,这些标签库不仅提供了表现层数据处理,而且提供了基本的流程控制功能,还提供了国际化、Ajax支持等功能。

通过使用Struts2的标签,开发者可以最大限度的减少页面代码的书写量。以下是使用Struts2标签实现的登录页面:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<%@ taglib uri="/struts-tags" prefix="s" %>

用户名:

密码:

其中标签用于生成HTML提交表单,标签用于生成HTML中的输入框。

5.1.3Struts2 运行流程

Struts2使用拦截器作为处理,以用户的业务逻辑控制器为目标,创建一个控制代理。控制器代理负责处理用户请求,处理用户请求时回调业务控制器的execute方法,该方法的返回值将决定了Struts2将怎样的视图资源呈现给用户。图1.5.1显示了Struts2运行流程。

图1.5.1 Struts2运行流程图

Struts2框架的处理流程如下:

(1)浏览器发送请求,例如请求/login.action

(2)核心控制器FilterDispatcher根据请求决定调用合适的Action

(3)WebWork的拦截器链自动对请求应用通用功能,例如workflow、validation或文件上传等功能

(4)回调Action的execute方法,该方法先获取用户请求参数并调用业务逻辑组件来处理用户请求

(5)Action的execute方法处理结果信息将被输出到浏览器中,可以是HTML页面、图像,也可以是

PDF文档或其它文档。此时支持的视图技术非常多,既支持JSP,也支持Velocity、FreeMarker等

模板技术。

5.2Struts2与Struts1的对比

`Struts2在Struts1上做出了巨大的改进,以下是Struts1和Struts2在各方面的简要对比。

(1)Action实现类方面:Struts1要求Action类需继承org.apache.struts.action.Action父类;Struts2中的Action

无需任何特定要求,只有一个包含execute方法的POJO类都可以用作Struts2的Action

(2)线程模式方面:Struts1中的Action是单例模式并且必须是线程安全的,因为仅有Action的一个实例来

处理所有请求,所以在Action中定义的资源必须是线程安全的或同步的;Struts2中的Action对象会为每个请求产生一个实例,因此没有线程安全问题。

(3)封装请求参数方面:Struts1使用ActionForm对象封装用户的请求参数,所有的ActionForm必须继承

org.apache.struts.action.ActionForm类,开发者必须创建大量的ActionForm类来封装用户请求参数;

Struts2直接使用Action属性来封装用户请求参数,避免了开发者需要大量开发ActionForm类。

(4)表达式语言方面:Struts1整合了JSTL,因此可使用JSTL表达式语言。这种表达式语言有基本对象图

遍历,但在对集合和索引属性的支持上则功能不强;Struts2可以使用JSTL,但同时整合了一种更强大和灵活的表达式语言:OGNL(Object Graph Notation Language 对象图形导航语言),因此,Struts2下的表达式语言功能更加强大。

(5)绑定值到视图方面:Struts1使用标签JSP机制把对象绑定到视图页面;Struts2使用ValueStack(值栈)

技术,使标签库能够访问值,而不需要将对象和视图页面绑定在一起。

5.3使用Struts2重构用户登录

在第一章中,我们使用Struts1框架开发过一个简单的用户登录示例,下面使用Struts2框架重构该示例。

重构该示例涉及到以下内容:

(1)导入Struts2框架jar包到Web工程

(2)创建模型

(3)创建控制器

(4)创建视图

(5)对Struts2框架进行配置

(6)发布、运行此示例

5.3.1导入Struts2框架jar包到Web工程

创建一个Web工程,命名为struts5l,从https://www.doczj.com/doc/ba13887303.html,/dist/struts/binaries/下载Struts2库文件(本示例使用2.1.6版本),下载后解压缩,在apps目录下找到struts2-blank-2.1.6.war文件。如图1.5.2所示:

图1.5.2 Struts2 apps目录文件列表

将struts2-blank-2.1.6.war文件解压缩,把其中lib目录下面的9个jar包,复制到项目的”WEB-INF/lib”

文件夹下,如图1.5.3所示:

图1.5.3 开发Struts2应用程序的jar包

5.3.2创建模型

本示例汲及到两个JavaBean。

(1)UserInfo.java:用于描述用户的实体类。代码如下:

public class UserInfo implements java.io.Serializable

{

private String uid;//用户名

private String pwd;//密码

private String realName;//真实姓名

private Date birthday;//出生日期

//无参构造函数

public UserInfo()

{

}

//有参构造函数

public UserInfo(String uid, String pwd, String realName, Date birthday) { super();

this.uid = uid;

this.pwd = pwd;

this.realName = realName;

this.birthday = birthday;

}

//getter、setter方法省略…

}

(2) UserService.java:用于处理业务逻辑的JavaBean。为了简化操作,本JavaBean模拟数据库来判断登录是否成功。代码如下:

public class UserService

{

//构造一个Map对象,用于存入UserInfo的集合

private Map userInfoMap=new HashMap();

//构造一个UserService静态对象,实现单例工厂模式

private static UserService userService=new UserService();

//构造函数私有,做成为单例模式,模拟数据库产生UserInfo的集合

private UserService()

{

try

{

//实例化一个SimpleDateFormat对象,用于转换字符串为日期

SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");

//实例化多个UserInfo类

UserInfo u1=new UserInfo("admin","admin","张三",sdf.parse("1978-3-4"));

UserInfo u2=new UserInfo("ht","ht","李四",sdf.parse("1980-11-12"));

UserInfo u3=new UserInfo("soft","soft","王五",sdf.parse("1979-12-4"));

UserInfo u4=new UserInfo("com","com","胡海军",sdf.parse("1987-7-4"));

UserInfo u5=new UserInfo("kitt","kitt","张小玲",sdf.parse("1985-6-4"));

//加入Map集合

userInfoMap.put(u1.getUid(), u1);//加入u1

userInfoMap.put(u2.getUid(), u2);//加入u2

userInfoMap.put(u3.getUid(), u3);//加入u3

userInfoMap.put(u4.getUid(), u4);//加入u4

userInfoMap.put(u5.getUid(), u5);//加入u5

}catch(Exception e)

{

e.printStackTrace();

}

}

//定义静态方法,实例化自己

public static UserService newInstance()

{

return userService;

}

public UserInfo login(String uid,String pwd)

{

//判断用户输入的用户名是否在集合中

if(https://www.doczj.com/doc/ba13887303.html,erInfoMap.containsKey(uid))

{

//存在,进一步比较密码是否正确

UserInfo findUserInfo=(UserInfo)https://www.doczj.com/doc/ba13887303.html,erInfoMap.get(uid);//通过uid键得到一个UserInfo

if(findUserInfo.getPwd().equals(pwd))//如果密码也相等,说明登录成功

{

return findUserInfo;

}

return null;//否则用户名相等,但密码不相等,登录失败

}

return null;//不存在,表明登录失败,返回null;

}

}

5.3.3创建控制器

Struts2下的控制器不再像Struts1下的控制器,需要继承一个Action父类,甚至可以无需实现任何接口,Struts2的控制器就是一个普通的POJO类。事实上,Struts2的Action就是一个包含execute 方法的普通Java类。以下是用于处理用户请求的Action类的代码:

public class LoginAction

{

//封装用户请求参数的uid属性

private String uid;

//封装用户请求参数的pwd属性

private String pwd;

//处理用户请求的execute方法

public String execute() throws Exception

{

//调用模型进行业务逻辑错误

UserInfo userInfo=UserService.newInstance().login(this.uid, this.pwd);

if(userInfo!=null) //如果登录成功

{

//转发到成功页面,该success与struts.xml配置文件中相对应

return "success";

}

//转发到失败页面,该fail与struts.xml配置文件中相对应

return "fail";

}

//getter、setter方法

public String getPwd() {

return pwd;

}

public void setPwd(String pwd) {

this.pwd = pwd;

}

public String getUid() {

return uid;

}

public void setUid(String uid) {

this.uid = uid;

}

}

5.3.4创建视图

本示例包括视图由三个JSP文件构成。

(1)login.jsp:用于提供登录页面,代码如下:

用户名:

密码:

(2)index.jsp:登录成功后的主页面,用于显示登录的用户信息。代码如下:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

恭喜你,登录成功!

(3)fail.jsp:登录失败后的错误页面。代码如下:

用户名或密码错误!

系统将在

5
秒后返回登录页面,要立即返回请点击登录

5.3.5配置Struts2应用程序

Struts2应用程序采用两个基于XML的配置文件来配置应用程序。这两个配置文件为web.xml和struts.xml,web.xml适用于所有的JavaWeb应用程序,它是Web应用程序的发布描述文件。对于

Struts2应用程序,还应该配置和Struts2相关的特殊信息。struts.xml文件是Struts2框架的专属配置文件,在该文件中可配置Action、拦截器、result等Struts2一系列组件

1.添加web.xml文件并配置FilterDispatcher

FilterDispatcher是Struts2框架的核心控制器,该控制器作为一个Filter运行在Web应用程序中,它负责拦截所有的用户请求,当用户请求到达时,该Filter会过滤用户请求。如果用户请求以action结尾,该请求将被转入Struts2框架处理。为了让FilterDispatcher过滤器起作用,必须在web.xml文件中进行相关的配置。在web.xml 文件中配置FilterDispatcher 代码如下:

struts2

org.apache.struts2.dispatcher.FilterDispatcher

struts2

/*

FilterDispatcher作为一个标准filter,配置在Web 应用中,负责拦截用户的所有请求。并且还有加载Struts2 配置文件的职责。但这里并未告诉它如何加载Struts2 的配置文件,以及Struts2 的配置文件放在哪里及文件名是什么。FilterDispatcher默认加载WEB-INF/classes 路径下的struts.xml文件。如果需要Struts2 的配置文件不在WEB-INF路径下,或者改变了文件名,则应采用如下方式配置:

struts2

org.apache.struts2.dispatcher.FilterDispatcher

config

struts-default.xml,struts-plugin.xml,../struts-config-user.xml

struts2

/*

在上面的配置中,指定了Struts2 的配置文件struts-config-user.xml 文件,并且该文件位于WEB-INF目录下。该文件作为init-param参数载入,载入时指定了参数名config。config 是Struts2 固定的参数名,Struts2负责解析该参数,并加载该参数的指定的配置文件。对于以上Struts2配置文件方式,需要注意以下2点:

(1)".."表示后退到WEB-INF目录,不能直接写成

struts-default.xml,struts-plugin.xml,struts-config-user.xml

(2)如果设置了config 参数, 那么struts-default.xml等struts2

默认加载的文件也需指定

2.添加Struts2配置文件并配置Action

Action是业务逻辑控制器,它负责获取用户提交的请求数据,并调用模型进行数据处理,然后根据处理结果,转发请求到不同的视图。下面是本示例LoginAction的配置代码:

"-//Apache Software Foundation//DTD Struts Configuration 2.1//EN"

"https://www.doczj.com/doc/ba13887303.html,/dtds/struts-2.1.dtd">

表1.5.1对Action配置属性做了说明。

表1.5.1 配置属性

3.配置Result

元素用于把一个逻辑名映射到特定的URL,通过这种方式,Action类或者JSP文件无需指定

实际的URL,只要指定逻辑名就能实现请求转发或者重定向,这可以减弱控制组件和视图之间的耦合,并且有助于维护JSP文件。下面是本示例Result的配置代码:

/index.jsp

/fail.jsp

表1.5.2对Result配置属性做了说明。

表1.5.2 配置属性

上面的映射文件定义了name为login的Action,即:该Action将负责处理login.action 的请求。该Action 将调用自身的execute方法,如果execute方法返回success字符串,请求将被转发到/index.jsp页面;如果execute方法返回fail字符串,则请求被转发到/fail.jsp页面。

以上在Action中配置的Result属于局部Result,局部Result只能被该Action引用。全局Result单独配置,所有的Action都可引用。全局的Result配置在global-results元素里。下面是配置全局Resul代码:

/error.jsp

可以为Web应用程序做一个专用于显示错误信息的页面error.jsp。然后给所有的Action都来共享。在这种情况下,可把error.jsp配置成全局的Result。

经过以上配置后,该示例struts-config-user.xml文件最终代码如下:

"-//Apache Software Foundation//DTD Struts Configuration 2.1//EN"

"https://www.doczj.com/doc/ba13887303.html,/dtds/struts-2.1.dtd">

/index.jsp

/fail.jsp

5.3.6 发布、运行此示例

通过MyEclipse 工具开发的struts5l 应用程序的目录结构如图1.5.4:

图1.5.4 struts5l 应用程序目录结构

发布此应用程序到Tomcat 容器中,在浏览器中输入:http://localhost:8080/struts5l/login.jsp 运行结果如图1.5.5:

图1.5.5 登录页面

输入用户名与密码,如果登录失败,会转到fail.jsp页面,如图1.5.6:

图1.5.6 登录失败页面

如果登录成功,会转到index.jsp页面,显示登录用户的详细信息,如图1.5.7:

图1.5.7登录成功index.jsp页面

5.4跟踪用户状态

上述Action处理完用户登录后,仅仅执行了简单的页面转发,并末跟踪用户状态信息,通常,当一个用户登录成功后,需要将用户信息添加到Session状态信息。为了访问HttpSession实例,Struts2提供了一个ActionContext类,该类提供了一个getSession方法,但该方法的返回值类型并不HttpSession 而是Map。实际上,Struts2为了简化Action类的测试,将Action类与Servlet API 完全分离,但Struts2的系列拦载器会负责Map和HttpSession之间的转换。为了可以跟踪会话信息,修改Action类的execute 方法,修改后的execute方法代码如下:

public class LoginAction

{

//封装用户请求参数的uid属性

private String uid;

//封装用户请求参数的pwd属性

private String pwd;

//处理用户请求的execute方法

public String execute() throws Exception

{

//调用模型进行业务逻辑错误

UserInfo userInfo=UserService.newInstance().login(this.uid, this.pwd);

if(userInfo!=null) //如果登录成功

{

//将userInfo的信息,添加到会话中

A ctionContext.getContext().getSession().put("userInfo", userInfo);

//转发到成功页面,该success与struts.xml配置文件中相对应

r eturn "success";

}

//转发到失败页面,该fail与struts.xml配置文件中相对应

return "fail";

}

//getter、setter方法

public String getPwd() {

return pwd;

}

public void setPwd(String pwd) {

this.pwd = pwd;

}

public String getUid() {

return uid;

}

public void setUid(String uid) {

this.uid = uid;

}

}

为了检验设置的Session属性是否成功,可修改index.jsp页面,在index.jsp页面中可使用EL(表达式语言)来输出Session中的UserInfo的属性。修改后的index.jsp页面代码如下:

${https://www.doczj.com/doc/ba13887303.html,erInfo.uid}欢迎你!

你的个人信息如下:


用户名:${https://www.doczj.com/doc/ba13887303.html,erInfo.uid }

真实姓名:${https://www.doczj.com/doc/ba13887303.html,erInfo.realName }

出生年月:

在图1.5.5所示的登录页面中,用户名输入“ht”,密码输入”ht”,单击“登录”按钮,将会看到如图

1.5.8所示的运行结果。

图1.5.8 修改后的index.jsp运行结果

5.5Struts2的ValueStack(值栈)

5.5.1什么是ValueStack

Strut2的Action类通过属性可以获得所有相关的值,如请求参数属性值等。要获得这些参数值,我们要做的唯一一件事就是在Action类中声明与参数同名的属性。在Struts2调用Action类的Action方法(默认是execute 方法)之前,就会为相应的Action属性赋值。要完成这个功能,有很大程度上,Struts2要依赖于ValueStack对象。这个对象贯穿整个Action的生命周期,每个Action类的对象实例会拥有一个ValueStack对象。

当Struts2接收到一个.action的请求后,会先建立Action类的对象实例,但并不会调用Action方法,而是先将Action类的相应属性放到ValueStack对象的顶层节点(ValueStack对象相当于一个栈)。只是所有的属性值都是默认的值,如String类型的属性值为null,int类型的属性值为0等。在处理完上述工作后,Struts 2就会调用拦截器链中的拦截器,这些拦截器会根据用户请求参数值去更新ValueStack对象顶层节点的相应属性的值,最后会传到Action对象,并将ValueStack对象中的属性值,赋给Action类的相应属性。当调用完所有的拦截器后,才会调用Action类的Action方法。ValueStack会在请求开始时被创建,请求结束时消亡。

5.5.2 为什么要使用ValueStack

在Struts1中,Action 为了能将处理的结果传递给下一个页面进行显示,通常需要借助于request 对象。而Struts2会自动的将ValueStack 与Action 中的属性关联,基于这一点,可在Action 中定义某

个属性,转发到JSP 页面后,直接从ValueStack 中取出数据,并显示。

5.5.3 如何使用ValueStack

对于大部分Web 应用程序而言,用户需要获得请求Action 的处理结果,例如,在线购物系统需要查询某个种类下的商品信息,则Action 调用业务逻辑组件的相关方法得到该种类下的全部商品,而JSP 页面则获取该Action 的处理结果,并将全部结果迭代输出。再次修改LoginAction 业务控制器,实现,如果用户成功登录,则获取某个系列的全部商品,并交由JSP 页面输出。为了让Action 可以获取这些商品,需要创建一个业务逻辑组件,命名为ShopService.java ,代码如下:

public class ShopService {

//构造一个ShopService 静态对象,实现单例工厂模式

private static ShopService shopService=new ShopService(); //构造函数私有,做成为单例模式 private ShopService() { }

//定义静态方法,实例化自己

public static ShopService newInstance() { return shopService;

}

//定义一个方法,用于获取某个系列的所有商品 public String[] getShopNames() { //模拟从数据库查询出的某系列商品集合

String[] shops={"彩电","空调","微波炉","电冰箱"}; return shops; }

}

再次修改LoginAction 业务控制器的代码,在其中使用ShopService 业务组件,代码如下:

{

//封装用户请求参数的 private String uid;

//封装用户请求参数的pwd 属性 private String pwd;

相关主题
文本预览
相关文档 最新文档