首页 > 代码库 > Strurs2总结

Strurs2总结

  • 必备jar文件

早在struts2.0.*的时候,struts2的必备jar包需要如下几个:

commons-logging-*.jar   Apache旗下commons项目的log日志包

freemarker-*.jar             一种前台页面模板,应用比较广泛

ognl-*.jar                        动态图导航语言,struts2处理前台页面的核心语言,相当实用

struts2-core-*.jar           struts2的核心包

xwork-core-*.jar             webwork的核心包,因为struts2的前身是webwork,所以这个是必须的

只要满足这5个基本jar包就可以运行一个struts2的hello world

(注:*表示版本号,struts2不同版本,使用的jar包版本也可能不一样。)

 

但是后面版本,比如struts-2.1.8.1,必须再添加一个新jar包才能运行,不然启动就会报错:

commons-fileupload-1.2.1.jar   支持文件上传的jar包

 

 

  • web.xml文件配置
在web.xml需要配置struts2滤镜,即当jsp向后台发送请求时需要经过struts2拦截分析处理,需要注意的是struts2与struts1和spring mvc的拦截机制不同,它是通过一个filter拦截的。
filter拦截器的类除了下面这个类以外,也可以引用“org.apache.struts2.dispatcher.FilterDispatcher”。
注意filter-mapping配置的url-pattern即拦截所有的请求,如果写成/*.action就只能拦截以.action结尾的请求。
<init-param>标签中的config指定struts2初始核心文件路径,struts.xml是最核心文件
Xml代码  技术分享
  1. <!-- struts2 滤镜配置  -->  
  2.     <filter>  
  3.         <filter-name>struts2</filter-name>  
  4. <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>  
  5.         <init-param>  
  6.             <param-name>config</param-name>  
  7.             <param-value>  
  8.             struts-default.xml,  
  9.             struts-plugin.xml,  
  10.             <!-- 核心struts.xml文件  -->  
  11.             ../conf/common/struts2/struts.xml,  
  12.             </param-value>  
  13.         </init-param>  
  14.     </filter>  
  15.   
  16.     <filter-mapping>  
  17.         <filter-name>struts2</filter-name>  
  18.         <url-pattern>/*</url-pattern>  
  19.     </filter-mapping>  
 
 
  • struts.xml文件配置
下面介绍一些struts2常用的配置信息,注意这些配置都有合适的默认值,不是必须的。
属性struts.i18n.encoding:指定字符集编码,这个配置经常用到;
属性struts.action.extension:指定JSP哪些后缀请求是struts2的请求,常用配置
属性struts.devMode:当系统发生异常,在浏览器打印详细的错误消息,产品上线时间以设为false关闭
属性struts.enable.DynamicMethodInvocation:是否允许OGNL在JSP中直接调用java方法,不推荐使用
标签include:项目大的话,通常都会写很多struts2配置文件,然后通过include标签将其它配置文件引进来,需要注意的是如果struts.xml文件放在src根目录下,include的内容是支持通配符的,但是如果struts.xml文件放在其它位置就不能用通配符了,必须老老实实写路径,下面这个include就是struts.xml放在conf目录后引用其它文件的方式。
Xml代码  技术分享
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <!DOCTYPE struts PUBLIC  
  3.         "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"  
  4.         "http://struts.apache.org/dtds/struts-2.0.dtd">  
  5. <struts>  
  6.       
  7.     <!--载入默认的struts配置-->  
  8.     <include file="struts-default.xml" />  
  9.   
  10.     <!--指定web应用的默认编码集,相当于调用HttpServletRequest的setCharacterEncoding方法-->  
  11.     <constant name="struts.i18n.encoding" value=http://www.mamicode.com/"UTF-8"></constant>  
  12.       
  13.     <!--该属性指定需要Struts 2处理的请求后缀,该属性的默认值是action,即所有匹配*.action的请求都由Struts 2处理  
  14.         如果用户需要制定多个请求后缀,则多个后缀之间以英文逗号隔开-->  
  15.     <constant name="struts.action.extension" value=http://www.mamicode.com/"action,do"></constant>  
  16.       
  17.     <!--设置浏览器是否缓存静态内容,默认值为true,生产环境下使用,开发阶段最好关闭 -->  
  18.     <constant name="struts.serve.static.browserCache" value=http://www.mamicode.com/"false"></constant>  
  19.       
  20.     <!--当struts的配置文件修改后,系统是否自动重新加载该文件,默认值为false,生产环境下使用,开发阶段最好打开 -->  
  21.     <constant name="struts.configuration.xml.reload" value=http://www.mamicode.com/"true"></constant>  
  22.       
  23.     <!--开发模式下使用,可以打印出更详细的错误信息 -->  
  24.     <constant name="struts.devMode" value=http://www.mamicode.com/"true" />  
  25.       
  26.     <!-- 动态方法调用 false为不允许 -->  
  27.     <constant name="struts.enable.DynamicMethodInvocation" value=http://www.mamicode.com/"true" />  
  28.       
  29.     <!-- 默认的视图主题,标签不支持label  ; theme属性包括xhtml,html,simple,ajax ,默认是xhtml-->  
  30.     <constant name="struts.ui.theme" value=http://www.mamicode.com/"simple"></constant>  
  31.       
  32.     <!--Struts2集成Spring:所有action对象由Spring来负责创建-->  
  33.     <constant name="struts.objectFactory" value=http://www.mamicode.com/"spring"></constant>  
  34.   
  35.     <!-- 支持页面使用静态方法和属性 -->  
  36.     <constant name="struts.ognl.allowStaticMethodAccess" value=http://www.mamicode.com/"true"></constant>  
  37.       
  38.     <!-- 跳转到登录页 -->  
  39.     <package name="CommonPackage" extends="struts-default" namespace="/common">  
  40.         <action name="toLoginPage">  
  41.             <result>/Web/login/page/login.jsp</result>  
  42.         </action>  
  43.     </package>  
  44.     <!-- 指定其它的配置文件路径 -->  
  45.     <include file="../conf/common/struts2/interceptor-common-exception.xml"></include>  
  46. </struts>  
 
 
  • 获取Servlet内置对象
基于java web开发,我们经常会使用到servlet的内置对象:request、session、application等,通过struts2框架获取内置对象有四种方式:
(1)通过ActionContext来获得,获取的对象是不基于Servlet容器的;
(2)通过ServletActionContext获得,获取的对象是Servlet内置对象
Java代码  技术分享
  1. //取得HttpServletRequest对象  
  2. HttpServletRequest request = ServletActionContext. getRequest();  
  3.   
  4. //取得HttpSession对象  
  5. HttpSession session = ServletActionContext. getRequest().getSession();  
(3)通过Struts2提供的IOC实现RequestAware,SessionAware,ApplicationAware三个接口的抽象方法
(4)通过Struts2提供的IOC实现ServletRequestAware,ServletContextAware这两个接口的抽象方法,这种方式个人比较推荐,你只需要创建一个BaseAction实现IOC,其它Action继承BaseAction,随后就直接调用内置对象即可:
Java代码  技术分享
  1. public class BaseAction extends ActionSupport implements ServletRequestAware,  
  2. ServletContextAware,ServletResponseAware{  
  3.     //配置序列化标志  
  4.     private static final long serialVersionUID = 1L;  
  5.       
  6.     //request,response,application,session作用域  
  7.     protected HttpServletRequest request ;  
  8.     protected ServletContext application;  
  9.     protected HttpServletResponse response;  
  10.     protected HttpSession session;  
  11.       
  12.     /** 
  13.      * 依赖servlet容器的IOC设置-start 
  14.      */  
  15.     @Override  
  16.     public void setServletRequest(HttpServletRequest arg0) {  
  17.         this.request = arg0;  
  18.         session = this.request.getSession();  
  19.     }  
  20.   
  21.     @Override  
  22.     public void setServletContext(ServletContext arg0) {  
  23.         this.application = arg0;  
  24.     }  
  25.   
  26.     @Override  
  27.     public void setServletResponse(HttpServletResponse arg0) {  
  28.         this.response = arg0;  
  29.     }  
  30.     /** 
  31.      * 依赖servlet容器的IOC设置-end 
  32.      */  
  33.   
  34.     //重写execute方法  
  35.     @Override  
  36.     public String execute() throws Exception {  
  37.         request.setAttribute("requestKey", "requestValue");  
  38.         session.setAttribute("sessionKey", "sessionValue");  
  39.         application.setAttribute("applicationKey", "applicationValue");  
  40.         return SUCCESS;  
  41.     }  
  42. }}  
 
 
  • OGNL对象图导航语言

OGNL是一个功能强大的EL,通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。它使用相同的表达式去存取对象的属性。因为太过复杂,这里就简单介绍几个常用的。

假设demo1.jsp页面有姓名name,年龄age这两个表单数据,它们被提交到action(action可以访问数据库保存或者比对或者更新),然后action再转发到demo2.jsp页面显示刚才输入的数据。

这是一个典型的B/S案例,我们可以将表单数据封装到一个JavaBean中(有的人喜欢叫pojo,还有的叫vo,还有的叫formbean),到demo2.jsp的时候通过ognl表达式取出来。

【demo1.jsp】

 

Html代码  技术分享
  1. <%@ page contentType="text/html; charset=UTF-8" language="java" import="java.util.*" pageEncoding="UTF-8"%>  
  2. <!--添加struts2标签的引用-->  
  3. <%@ taglib prefix="s" uri="/struts-tags" %>  
  4. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
  5. <html>  
  6.     <head>  
  7.     </head>  
  8.     
  9.     <body>  
  10.         <s:form action="doSaveAction.action" method="post">  
  11.         <s:textfield  name="user.name">姓名:</s:textfield>  
  12.         <s:textfield name="user.age">年龄:</s:textfield>  
  13.         <s:submit value=http://www.mamicode.com/"提交"></s:submit>  
  14.         </s:form>  
  15.     </body>  
  16. </html>  

 

  【User.java】

 

Java代码  技术分享
  1. public class User{  
  2.   private String name;  
  3.   private String age;  
  4.   ...get、set方法...  
  5. }  
  【SaveAction.java】
Java代码  技术分享
  1. public class SaveAction extends ActionSupport{  
  2.     private static final long serialVersionUID = 1L;  
  3.     //将User这个javabean创建set方法便能获得从jsp请求过来的user对象数据  
  4.     //同时user对象会放在值栈中,在demo1.jsp--SaveAction--demo2.jsp这个生命周期都存在  
  5.     private User user;  
  6.   
  7.     public String doSave(){  
  8.         return SUCCESS;  
  9.     }  
  10.       
  11.     public User getUser() {  
  12.         return user;  
  13.     }  
  14.     public void setUser(User user) {  
  15.         this.user = user;  
  16.     }  
  17. }  
  【demo2.jsp】
Java代码  技术分享
  1. <s:property value=http://www.mamicode.com/"user.name"/>  
  2. <s:property value=http://www.mamicode.com/"user.age"/>  
之所以命名为OGNL,就是因为它处理对象很给力,struts能够将对象层层解析,把各个对象的关系以图的样式展示出来。比如user.name,之所以能找到这个对象,就是因为OGNL会先找user对象,然后再找user对象里的name对象。假设User这个类还包含了名为Role的javabean的实例,Role里面包含字段roleName,我们要找到roleName就可以直接写<s:property value="http://www.mamicode.com/user.role.roleName">,OGNL通过对象逐级导航找到子对象。

当然OGNL也可以像jsp一样调用后台代码,不过我发现在jsp调用后台代码的效率很低,所以不是很推荐。

ognl调用静态方法的写法如下:@类全名@静态方法名,这句话等同于java代码:类全名.静态方法名

Html代码  技术分享
  1. 运行静态方法:<s:property value=http://www.mamicode.com/"@com.bless.ssh2.action.OgnlAction@staticMethod()"/><br/>  
  2. 运行值栈对象中的方法:<s:property value=http://www.mamicode.com/"user.method()"/><br/>  
  3. 调用JDK中的静态方法:<s:property value=http://www.mamicode.com/"@java.lang.Math@floor(44.56)"/><br/>  
   需要注意的是,struts2.1.*默认是不允许调用静态方法的,你需要在struts.xml配置这样一句话:

<constant name="struts.ognl.allowStaticMethodAccess" value="http://www.mamicode.com/true"/>

下面这个是早前自己写的Struts2标签库的例子,内容肯定不全:

Html代码  技术分享
  1. <body>  
  2. <!-- "%{}"表示支持ognl表达式,"#u"表示从值栈的actioncontex中查找值 -->  
  3. <s:form action="doTags.action">  
  4. <h3>常用标签库</h3>  
  5. <table>  
  6.     <tr>  
  7.         <td>编号:</td>  
  8.         <!-- 直接获取后台的值 -->  
  9.         <td><s:property value=http://www.mamicode.com/"tagBean.id"></s:property></td>  
  10.     </tr>  
  11.   
  12.     <tr>  
  13.         <td>姓名:</td>  
  14.         <!-- 文本框 -->  
  15.         <td><s:textfield name="tagBean.name"></s:textfield></td>  
  16.     </tr>  
  17.       
  18.     <tr>  
  19.         <td>密码:</td>  
  20.         <!-- 密码框 -->  
  21.         <td><s:password name="tagBean.password"></s:password></td>  
  22.     </tr>  
  23.       
  24.     <tr>  
  25.         <td>生日:</td>  
  26.         <td>  
  27.         <!-- 在文本框中格式化时间 -->  
  28.         <s:textfield name="tagBean.birthday">  
  29.             <s:param name="value">  
  30.                 <s:date name="tagBean.birthday" format="yyyy-MM-dd hh:MM:ss" />  
  31.             </s:param>  
  32.         </s:textfield>  
  33.         </td>  
  34.         <td>生日:</td>  
  35.         <!-- 时间标签,可以格式化滴 -->  
  36.         <td><s:date name="tagBean.birthday" format="yyyy年MM月dd日"></s:date></td>  
  37.     </tr>  
  38.       
  39.     <tr>  
  40.         <td>性别:</td>  
  41.         <td><s:radio name="tagBean.sex" list="#request.lstSex" listKey="sexId" listValue=http://www.mamicode.com/"sexValue"></s:radio></td>  
  42.     </tr>  
  43.       
  44.     <tr>  
  45.         <td>城市:</td>  
  46.         <!-- listKey:下拉列表被选中后的真实值,listValue:下拉列表被选中后的显示值,headerKey:默认值,headerValue:默认显示值,emptyOption:是否在默认值和实际值下拉列表之间加一个空行 -->  
  47.         <td><s:select name="tagBean.city" list="#request.lstCity" listKey="cityId" listValue=http://www.mamicode.com/"cityValue" headerKey="0" headerValue=http://www.mamicode.com/"--请选择--"  emptyOption="true"></s:select></td>  
  48.     </tr>  
  49.       
  50.     <tr>  
  51.         <!-- 此标签等同于:struts2.tags.ListAddress la = new struts2.tags.ListAddress(); -->  
  52.         <!-- 此标签需要启用struts2的一个配置常量:<constant name="struts.enable.DynamicMethodInvocation" value="http://www.mamicode.com/true" />,通常不推荐使用此法,在这只是做个例子 -->  
  53.         <s:bean name="struts2.tags.ListAddress" id="la"></s:bean>  
  54.         <td>地区:</td>  
  55.         <!-- s:checkboxlist标签支持多个checkbox, s:checkbox只支持单个checkbox-->  
  56.         <td><s:checkboxlist name="tagBean.address" list="#la.lstAddress" listKey="addressId" listValue=http://www.mamicode.com/"addressValue"></s:checkboxlist></td>  
  57.     </tr>  
  58. </table>  
  59. <!-- hidden标签存放隐藏值 -->  
  60. <s:hidden></s:hidden>  
  61. <s:submit value=http://www.mamicode.com/"确定"></s:submit>  
  62. <s:reset value=http://www.mamicode.com/"重置"></s:reset>  
  63. <hr/>  
  64. <h3>OGNL</h3>  
  65. <table>  
  66.     <!-- #符号: 获取值栈中的作用域 [parameters]路径中传参,[request][session][application]这几个不用说,[attr]表示从parameters到application依次找-->  
  67.     <!-- %{}符号:可以获取值栈中的对象,可以使用ognl表达式 -->  
  68.     <!-- 如果需要用到直接调用静态方法,需要启用struts2的一个配置常量:<constant name="struts.ognl.allowStaticMethodAccess" value="http://www.mamicode.com/true"/> -->  
  69.     <tr>  
  70.         <td>直接调用静态方法:</td>  
  71.         <td><s:property value=http://www.mamicode.com/"@struts2.tags.Ognl@staticMethod()"/></td>  
  72.     </tr>  
  73.     <tr>  
  74.         <td>直接调用静态属性:</td>  
  75.         <td><s:property value=http://www.mamicode.com/"@struts2.tags.Ognl@STATIC"/></td>  
  76.     </tr>  
  77.     <tr>  
  78.         <td>调用值栈对象中的普通方法:</td>  
  79.         <td><s:property value=http://www.mamicode.com/"tagBean.normalMethod()"/></td>  
  80.     </tr>  
  81.     <tr>  
  82.         <td>调用JDK的静态方法(带参):</td>  
  83.         <td><s:property value=http://www.mamicode.com/"@java.lang.Math@floor(11.11)"/></td>  
  84.         <td>吓死你:</td>  
  85.         <!-- 如果第一个@后不带任何类,就默认表示java.lang.Math这个工具类,其它类不能这样写 -->  
  86.         <td><s:property value=http://www.mamicode.com/"@@floor(22.22)"/></td>  
  87.     </tr>  
  88.     <tr>  
  89.         <td>new一个对象:</td>  
  90.         <td><s:property value=http://www.mamicode.com/"new struts2.tags.Ognl(‘构造参数‘).result"></s:property></td>  
  91.     </tr>  
  92.     <tr>  
  93.         <td>#获取request数据:</td>  
  94.         <td><s:property value=http://www.mamicode.com/"#request.lstCity"></s:property></td>  
  95.     </tr>  
  96.     <tr>  
  97.         <td>#获取session数据:</td>  
  98.         <td><s:property value=http://www.mamicode.com/"#session.sess"></s:property></td>  
  99.     </tr>  
  100.     <tr>  
  101.         <td>下标-获取List集合第一条数据:</td>  
  102.         <td><s:property value=http://www.mamicode.com/"#request.lstCity[0]"></s:property></td>  
  103.         <!-- 注:Set集合是无序的所以不能通过下标获取数据;Map集合是键值对的,获取的时候应该根据key找value:map[‘key‘] -->  
  104.     </tr>  
  105.     <tr>  
  106.         <td>获取List数据总条数:</td>  
  107.         <td><s:property value=http://www.mamicode.com/"#request.lstCity.size"></s:property></td>  
  108.     </tr>  
  109.     <tr>  
  110.         <td>投影技术获取List中指定对象数组:</td>  
  111.         <td><s:property value=http://www.mamicode.com/"#request.lstCity.{cityValue}"></s:property></td>  
  112.     </tr>  
  113.     <tr>  
  114.         <td>投影技术+下标获取一个值:</td>  
  115.         <td><s:property value=http://www.mamicode.com/"#request.lstCity.{cityValue}[0]"></s:property></td>  
  116.     </tr>  
  117.     <tr>  
  118.         <td>选择器:</td>  
  119.         <td><s:property value=http://www.mamicode.com/"#request.lstCity.{#this.cityId<=2}"></s:property></td>  
  120.     </tr>  
  121.     <tr>  
  122.         <td>选择器(?)+投影</td>  
  123.         <!-- ?表示获得所有满足条件的对象 -->  
  124.         <td><s:property value=http://www.mamicode.com/"#request.lstCity.{?#this.cityId<=2}.{cityId}"></s:property></td>  
  125.     </tr>  
  126.     <tr>  
  127.         <td>选择器(^)+投影</td>  
  128.         <!-- ^表示取得第一个满足条件的元素 -->  
  129.         <td><s:property value=http://www.mamicode.com/"#request.lstCity.{^#this.cityId<=2}.{cityId}"></s:property></td>  
  130.     </tr>  
  131.     <tr>  
  132.         <td>选择器($)+投影</td>  
  133.         <!-- $表示取得最后一个满足条件的元素 -->  
  134.         <td><s:property value=http://www.mamicode.com/"#request.lstCity.{$#this.cityId<=2}.{cityId}"></s:property></td>  
  135.     </tr>  
  136.     <tr>  
  137.         <td>Top语法:</td>  
  138.         <!-- .top取栈中的对象 ,[n]表示获取栈中第几个对象(从0开始)-->  
  139.         <td><s:property value=http://www.mamicode.com/"[0].top.locale"></s:property></td>  
  140.     </tr>  
  141.     <tr>  
  142.         <td>[n]语法:</td>  
  143.         <!-- [n]表示获取栈中第几个对象(从0开始)-->  
  144.         <td><s:property value=http://www.mamicode.com/"[0].locale"></s:property></td>  
  145.     </tr>  
  146. </table>  
  147. <hr/>  
  148. <h3>逻辑,迭代标签</h3>  
  149. <!-- test代码块中支持其它数据类型,如果是int的可以这样:test="#request.if==1" -->  
  150. --if标签--  
  151. <s:if test="#request.if==‘if‘">  
  152.     这里是if模块  
  153. </s:if><s:elseif test="#request.if==‘elseif‘">  
  154.     这里是elseif模块  
  155. </s:elseif><s:else>  
  156.     这里是else模块  
  157. </s:else>  
  158. <br/><br/>  
  159. --循环标签①--  
  160. <!-- first表示起始值,last表示结束值 iterator表示内部循环代码-->  
  161. <s:bean name="org.apache.struts2.util.Counter" id="counter">  
  162.    <s:param name="first" value=http://www.mamicode.com/"3" />  
  163.    <s:param name="last" value=http://www.mamicode.com/"10" />  
  164.    <s:iterator>  
  165.      <s:property/>&nbsp;  
  166.    </s:iterator>  
  167. </s:bean>  
  168. <br/><br/>  
  169. --循环标签②--  
  170. <s:iterator  begin="1" end="10">  
  171.     <s:property/>  
  172. </s:iterator>  
  173.   
  174. <br/><br/>  
  175. --迭代list--  
  176. <!--  等同于for(int i=1;i<=lstCity.size;i++) 标签同样从0开始计数 -->  
  177. <s:iterator value=http://www.mamicode.com/"#request.lstCity" status="st" var="value" begin="1" end="#request.lstCity.length">  
  178.     [<s:property value=http://www.mamicode.com/"%{#attr.st.index+1}"/>]  
  179.     <s:property value=http://www.mamicode.com/"%{#attr.value.cityValue}"/>  
  180.     <!-- 或者使用EL表达式取值:${value.cityId}  -->  
  181. </s:iterator>  
  182. </s:form>  
  183. <s:debug></s:debug>  
  184. </body>  
Html代码  技术分享
  1. <tr>  
  2.         <td>生日:</td>  
  3.         <td>  
  4.         <!-- 在文本框中格式化时间 -->  
  5.         <s:textfield name="tagBean.birthday">  
  6.             <s:param name="value">  
  7.                 <s:date name="tagBean.birthday" format="yyyy-MM-dd hh:MM:ss" />  
  8.             </s:param>  
  9.         </s:textfield>  
  10.         </td>  
  11.         <td>生日:</td>  
  12.         <!-- 时间标签,可以格式化滴 -->  
  13.         <td><s:date name="tagBean.birthday" format="yyyy年MM月dd日"></s:date></td>  
  14.     </tr>  
 
  • 拦截器
struts2的核心内容是拦截器,拦截器的作用简单理解就是:在JSP向后台发送请求,访问某个方法之前或之后会运行拦截器处理一些特殊操作,比如异常拦截器,当运行后台某方法发生异常时会被拦截器截获并进行一些特殊处理:
Xml代码  技术分享
  1. <struts>  
  2.     <package name="bless-default" extends="struts-default" >  
  3.         <interceptors>  
  4.             <!--定义一个名为privilege的拦截器-->    
  5.              <interceptor    
  6.                 class="....ExceptionHandler"    
  7.                 name="exceptionInterceptor"/>    
  8.               
  9.             <!--①定义一个包含异常处理的拦截器栈-->    
  10.             <interceptor-stack name="exceptionStack">  
  11.                 <!-- 默认的拦截器 -->  
  12.                 <interceptor-ref name="defaultStack"/>  
  13.                 <!-- 异常拦截器 -->  
  14.                 <interceptor-ref name="exceptionInterceptor"/>          
  15.             </interceptor-stack>  
  16.               
  17.             <!-- ③需要用到chain跳转的拦截器栈 -->  
  18.             <interceptor-stack name="chainStack">  
  19.                 <interceptor-ref name="chain"/>  
  20.                 <interceptor-ref name="basicStack"/>  
  21.                 <interceptor-ref name="exceptionInterceptor"/>  
  22.             </interceptor-stack>  
  23.         </interceptors>  
  24.           
  25.         <!-- 默认运行的拦截器栈 -->  
  26.         <default-interceptor-ref name="exceptionStack" />   
  27.           
  28.         <global-results>  
  29.             <result name="error" >/Web/common/page/error.jsp</result>  
  30.         </global-results>  
  31.           
  32.         <global-exception-mappings>  
  33.             <exception-mapping result="error" exception="java.lang.Exception"></exception-mapping>  
  34.         </global-exception-mappings>  
  35.           
  36.     </package>  
  37. </struts>  
自定义一个拦截器非常简单:首先继承AbstractInterceptor类,实现intercept(ActionInvocation actioninvocation)方法即可:
Java代码  技术分享
  1. public class ExceptionHandler extends AbstractInterceptor {  
  2.     private static final long serialVersionUID = 1L;  
  3.   
  4.     public String intercept(ActionInvocation actioninvocation) {  
  5.   
  6.         String result = null; // Action的返回值  
  7.         try {  
  8.             // 运行被拦截的Action,期间如果发生异常会被catch住  
  9.             result = actioninvocation.invoke();  
  10.             return result;  
  11.         } catch (Exception e) {  
  12.             /** 
  13.              * 处理异常 
  14.              */  
  15.             String errorCode = null; // ospms的异常  
  16.             int errorId = -1; // 达运的异常  
  17.   
  18.             if (e instanceof FunctionException) {  
  19.                 // OSPMS异常  
  20.                 FunctionException fe = (FunctionException) e;  
  21.                 errorCode = fe.getErrorCode();  
  22.                 fe.printStackTrace();  
  23.             }...........  
  24.             /** 
  25.              * 发送错误消息到页面 
  26.              */  
  27.             ...........  
  28.           
  29.             /** 
  30.              * log4j记录日志 
  31.              */  
  32.             ...........  
  33.   
  34.             return "error";  
  35.         }// ...end of catch  
  36.     }  
  37. }   
   需要注意的是:异常拦截器XML配置文件一定要在struts.xml中include进来,很多朋友说拦截器不起作用,多半是因为这个问题。
 
  • 总结
Struts2是一个非常优秀的MVC框架,在开发中或多或少会遇到这样那样的问题,只有多总结多尝试才能找到问题的根源。

Strurs2总结