- Struts2 基础开发
- Struts2 并不是新发布的新框架,而是在另一个非常流行的框架:WebWork 基础上发展起来的。因此,可以说,Struts2 并没有继承 Struts1 的特点,反而和 WebWork 非常类似;换句话说,Struts2 是衍生自 WebWork,而不是 Struts1。正是由于这个原因,Struts2 吸引了众多的 WebWork 开发人员来进行使用。并且由于 Struts2 是 WebWork 的升级,在各种 功能和性能方面都有很好的保证,吸收了 Struts1 和 WebWork 两者的优势,因此也是一个非常优秀的框架
2.Struts2 和 Struts1 具有一些不同点,主要集中在以下方面:
(1)Action 类的编写:
在 Struts1 中, Action 类一般继承基类 org.apache.struts.action.Action。
而在 Struts2 中,Action 类可以实现一个 Action 接口,也可实现其他接口,也可以继承 ActionSupport 基类,甚至不需要实现任何接口,只编写 execute 函数即可
(2)Action 的运行模式:
Struts1 中,Action 是单态的,系统实例化一个对象来处理多个请求,为每个请求分配一 个线程,在该线程中运行 execute 函数。
因此,在开发时需要特别小心,Action 资源必须是线程安全的或同步的。
但是,Struts2 中,Action 为每一个请求产生一个实例,不会产生线程安全问题。
但是,系统又能够及时回收垃圾资源,不会有废弃空间的问题
(3)对 Web 容器的依赖:
Struts1 中,Action 的 execute 函数内,传入了 Servlet API:HttpServletRequest 和HttpServletResponse,使得测试必须依赖于 Web 容器。
但是,在 Struts2 中,可以不传入 HttpServletRequest 和 HttpServletResponse ,但是也可以访问它们,因此,Action 不依赖于容器,允许 Action 脱离容器单独被测试
(4)对表单数据的封装:
Struts1 中 , 使 用 ActionForm 来 封 装 表 单 数 据 , 所 有 的 ActionForm 必 须 继 承 org.apache.strtus.action.ActionForm,有可能造成 ActionForm 类和 VO 类重复编码。
但是,Struts2中,直接在 Action 中编写表单数据相对应的属性,可以不用编写 ActionForm,而这些属 性又可以通过 Web 页面上的标签访问
- Struts2 的基本原理
(一)环境配置
要编写基于Struts2 的应用,需要导入一些支持的包,也就是Struts2 开发包。这些开发包可以到网上去下载。下载地址为:"http://struts.apache.org/"http://struts.apache.org/
(二)Struts2中的MVC
(三)其执行步骤为:
1.用户输入,JSP 表单的请求被 过滤器FilterDispatcher 截获
2.FilterDispatcher 将表单信息转交给 Action,并封装在 Action 内
3.Action 来调用 JavaBean(DAO)
4.Action 返回要跳转到的 JSP 页面逻辑名称给框架
5.框架根据逻辑名称找到相应的网页地址,进行跳转,结果在 JSP 上显示
Struts2框架的大致处理流程
我们看下刚才的过程
1、浏览器发送请求,例如请求/login.action等
2、核心控制器FilterDispatch根据请求决定调用合适的action,如loginAction
3、拦截器自动对请求应用通用功能,如conversion、validation等功能
4、回调Action的execute方法,该execute方法先获取用户请求参数,然后调用业务逻辑组件来处理用户的请求
5、Action的excute方法处理result信息将被输出到浏览器中,可以是HTML页面,图像,也可以是PDF文档或其他文档
loginDemo应用的组成
4.Struts2 的基本使用方法
(一)导入 Struts2框架
(二)编写JSP
(三)编写并配置 ActionForm
在 Struts1.x 中,必须要单独建立一个 ActionForm 类,而在 Struts2 中 ActionForm和 Action 已经合二为一了。因此,只需要将和表单元素同名的属性编写到 Action 内。Action只是一个普通的类。在包 prj12 内新建一个类:LoginAction.java
LoginAction 没有继承任何类,它有属性 account 和 password,
与login.jsp 中的 表单元素account 与 password 必须同名
- 编写并配置 Action
1.Struts2 中,既然 Action 和 ActionForm 合二为一,Action 是负责业务逻辑的,所以必须 编写业务逻辑代码。
下面来加强 Action 的功能。要能够处理业务逻辑,必须要满足一个规范,那就是:编写 execute 方法来处理业务逻辑。注意,不是重写,是编写。并且该方法不需要有任何的参数
2.编写 execute 方法,是因为 Action 接收数据后,由框架自动调用它的 execute 方法,该方法的运行,在底层通过反射机制进行。execute 的格式为:
public String execute(){}
该函数返回一个字符串,表示的是目标页面的虚拟名称
- 在配置文件中进行配置,这一步在Struts1.x和Struts2.x中都是必需的,只是在Struts1.x中的配置文件一般叫struts-config.xml,而且一般放到WEB-INF目录中。
而在Struts2.x中的配置文件一般为struts.xml,一般放在WEB-INF/class目录中,编写时放在项目的src根目录下,前面已经叙述过了,下面是在Struts.xml中配置Action以及相关虚拟页面名称
配置文件
<struts>
<package name="struts2" extends="struts-default">
<action name="login" class="prj12.LoginAction">
<result name="success">/loginSuccess.jsp</result>
<result name="fail">/loginFail.jsp</result>
</action>
</package>
</struts>
从以上配置可以看出,在<struts>标签中可以有多个<package>,名称任意,但不要重名;extends 属性表示继承一个默认的配置文件"struts-default",一般都继承于它,可以不用修改。<action>标签中的 name 属性表示 Action 被提交时的路径,class 指定动作类路径
另外,通过<result>标签可以确定虚拟名称和实际页面路径的映射,如
<result name=“success”>/loginSuccess.jsp</result>
表示“/loginSuccess.jsp”对应的虚拟名称为“success”,当Action的execute函数返回“success”时,程序将跳转到“/loginSuccess.jsp”
由于<action>标签中的name属性表示Action被提交时的路径,此处为“login”,因此,在login.jsp中,表单要提交到路径就可以确定为:/Prj12/login.action,这是WebWork的风格,其中的“.action”是默认情况下规定的,因此,login.jsp可以改为p194页所示代码
(五)程序运行流程
1. login.jsp 中的表单 提交到 的地址为"/Prj12/login.action" ,被 org.apache.struts2.dispatcher.FilterDispatcher 截获,
框架把提交的地址的项目名称和扩展名 ".action"去掉,变为"/login",读取配置文件
- 在配置文件中,根据"/login",找到配置文件中的 action 对应的类,从而得到要提交到的类 LoginAction;在 LoginAction 中,实例化对象,将 account 和 password 封装进去
- 框架调用 LoginAction 的 execute 方法,处理后返回一个字符串
- 框架根据字符串内容,在配置文件中找到相应的页面,并跳转
(六)Action 生命周期p195
1. 框架先实例化 LoginAction 对象,然后调用 LoginAction 的 setAccount 函数,封装表单数据,然后调用 execute 函数,进行处理
2. 在第二次提交时,LoginAction 会重新实例化,说明每一个 LoginAction 对象都服务一个请求,这和 Servlet 的原理是不一样的
(七)在 Action 中访问 Web 对象
1.从前面可以看出,和Struts1相比,Struts2中action只是一个简单的类,增加了可测试性,但是在这个案例中会有如下问题:如何在Action中访问Web对象,如request、response、session
获得 request 对象的方法是:
import org.apache.struts2.ServletActionContext;
public String execute() throws Exception {
HttpServletRequest request = ServletActionContext.getRequest();
//使用 request
}
获得 application 对象的方法是:
import org.apache.struts2.ServletActionContext;
public String execute() throws Exception {
ServletContext application = ServletActionContext.getServletContext();
//使用 application
}
获得 session 对象的方法是:
import com.opensymphony.xwork2.ActionContext;
public String execute() throws Exception {
Map session = ActionContext.getContext().getSession();
//使用 session
}
可以发现这里的 session 是个 Map 对象。在 Struts2 中,底层的 session 被封装成了 Map类型,我们可以直接操作这个 map 进行对 session 的写入和读取操作,而不用去直接操作HttpSession 对象
- 总结
1.Struts2的配置文件
配置Action的Struts.xml文件
2.Struts2的控制器组件
Struts2的控制器组件是Struts2框架的核心,事实上,所有MVC框架都是以控制器组件为核心的
Struts2控制器由两部分组成:
核心控制器FilterDispatcher
业务逻辑控制器Action
3.Struts2的Action有如下优势:
1、Action类可以完全是一个POJO,因此具有很好的代码复用性
2、Action类无需与servlet API耦合,因此进行单元测试非常简单
3、Action类的execute方法仅返回一个字符串作为出来结果,该处理结果可映射到任何的视图,甚至是另一个Action