Struts2
1.1 Struts2概述
Struts 2是Struts的下一代产品。是在 struts 和WebWork的技术基础上进行了合并,全新的Struts 2框架。其全新的Struts 2的体系结构与Struts 1的体系结构的差别巨大。Struts 2以WebWork为核心,采用拦截器的机制来处理用户的请求,这样的设计也使得业务逻辑控制器能够与Servlet API完全脱离开,所以Struts 2可以理解为WebWork的更新产品。因为Struts 2和Struts 1有着太大的变化,但是相对于WebWork,Struts 2只有很小的变化。
1.2 Struts2体系结构
Struts2的体系与Struts1体系的差别非常大,因为Struts2使用了WebWork的设计核心,而不是Struts1的设计核心。Struts2中大量使用拦截器来处理用户的请求,从而允许用户的业务逻辑控制器与Servlet API分离。图一是Struts2的体系结构简图。
Struts2框架的大概处理流程如下:
1. 加载类(FilterDispatcher)
2. 读取配置(struts配置文件中的Action)
3. 派发请求(客户端发送请求)
4. 调用Action(FilterDispatcher从struts配置文件中读取与之相对应的Action )
5. 启用拦截器(WebWork拦截器链自动对请求应用通用功能,如验证)
6. 处理业务(回调Action的execute()方法)
7. 返回响应(通过execute方法将信息返回到FilterDispatcher)
8. 查找响应(FilterDispatcher根据配置查找响应的是什么信息如:SUCCESS、ERROER,将跳转到哪个jsp页面)
9. 响应用户(jsp--->客户浏览器端显示)
1.3 Struts2和Struts1的对比
通过上面对Struts2体系结构的了解,我们发现Struts2对Struts1进行了巨大的改进。主要表现在如下几个方面:
1. 在Action的实现方面:Struts1要求必须统一扩展自Action类,而Struts2中可以是一个普通的POJO。
2. 线程模型方面:Struts1的Action工作在单例模式,一个Action的实例处理所有的请求。Struts2的Action是一个请求对应一个实例。没有线程安全方面的问题。
3. Servlet依赖方面:Struts1的Action依赖于Servlet API,比如Action的execute方法的参数就包括request和response对象。这使程序难于测试。Struts2中的Action不再依赖于Servlet API,有利于测试,并且实现TDD。
4. 封装请求参数:Struts1中强制使用ActionForm对象封装请求的参数。Struts2可以选择使用POJO类来封装请求的参数,或者直接使用Action的属性。
5. 表达式语言方面:Struts1中整合了EL,但是EL对集合和索引的支持不强,Struts2整合了OGNL(Object Graph NavigationLanguage)。
6. 绑定值到视图技术:Struts1使用标准的JSP,Struts2使用“ValueStack”技术。
7. 类型转换:Struts1中的ActionForm基本使用String类型的属性。Struts2中使用OGNL进行转换,可以更方便的使用。
8. 数据校验:Struts1中支持覆盖validate方法或者使用Validator框架。Struts2支持重写validate方法或者使用XWork的验证框架。
9. Action执行控制的对比:Struts1支持每一个模块对应一个请求处理,但是模块中的所有Action必须共享相同的生命周期。Struts2支持通过拦截器堆栈为每一个Action创建不同的生命周期。
1.4 WebWork和Struts2的对比
Struts和Webwork同为服务于Web的一种MVC框架,从某种程度上看,Struts2是从WebWork2上升级得到的。甚至Apache的官方文档也讲:WebWork2到Struts2是平滑的过渡。我们甚至也可以说Struts2就是WebWork2.3而已。在很多方面Struts仅仅是改变了WebWork下的名称。Struts2对应的有自己的标签,并且功能强大。Webwork也有自己的标签。在2005年12月,WebWork与Struts Ti决定合拼, 再此同时, Struts Ti 改名为 Struts Action Framework 2.0,成为Struts真正的下一代。
1.5 Struts2 五种默认返回类型名
ActionSupport基类中定义了五个标准的返回值 ,当然我们可以自己随意定义返回的名字
String SUCCESS = "success"; //默认是 SUCCESS 类型
String NONE = "none";
String ERROR = "error";
String INPUT = "input";
String LOGIN = "login";
1.6 Struts2实例
实例基于Strtus2.2.1版本。
1. 第一步创建web应用程序
点击Finish按钮,完成web应用程序创建。
接下来我们测试一下web应用程序是否创建成功。
OK web应用程序创建成功。
1. 第二步 导入Struts2.2.1所需包
将所有包复制到web项目的lib目录下面:
接下来我们在web应用项目中添加struts2配置,web.xml增加代码如下:
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" 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-app_2_5.xsd"> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> <!-- 如果是2.1.3之前的版本,用org.apache.struts2.dispatcher.FilterDispatcher, 否则,用org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilte --> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
接下来我们在web应用项目src下建立struts.xml文件,内容如下:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <package name="hello" extends="struts-default"> <action name="helloAction" class="net.hello.action.HelloAction" method="hello"> <result name="success">/jsp/hello/result.jsp</result> <result name="error">/jsp/system/error.jsp</result> </action> </package> </struts>
建立hello.jsp页,内容如下:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <%@ taglib prefix="s" uri="/struts-tags" %> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>你好</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <s:form action="helloAction" > <s:textfield name="strTemp" label="输入内容"/> <s:submit name="helloSubmit" value="提交" /> </s:form> </body> </html>
建立result.jsp页,内容如下:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <%@taglib uri="/struts-tags" prefix="s"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>结果</title> </head> <body> <s:property value="strTemp" default="未知错误" /> </body> </html>
建立HelloAction.java页,内容如下:
package net.hello.action; import com.opensymphony.xwork2.ActionSupport; /** * @项目名:struts2.1.1 * @包名:net.hello.action * @文件名:Hello.java * @日期:Jun 14, 2011 4:22:02 PM * @备注: * @作者:apple */ public class HelloAction extends ActionSupport { /** * */ private static final long serialVersionUID = 1L; private String strTemp; private String strMsg; private String strUrl; public String hello() { String reString="error"; if(this.strTemp!=null&&!this.strTemp.equals("")) { reString="success"; } else { this.strMsg="输入的内容为空"; this.strUrl="jsp/hello/hello.jsp"; } return reString; } public String getStrTemp() { return strTemp; } public void setStrTemp(String strTemp) { this.strTemp = strTemp; } public static long getSerialVersionUID() { return serialVersionUID; } public String getStrMsg() { return strMsg; } public void setStrMsg(String strMsg) { this.strMsg = strMsg; } public String getStrUrl() { return strUrl; } public void setStrUrl(String strUrl) { this.strUrl = strUrl; } }
接下来我们发布项目来看下效果: