Struts2 Interceptor 拦截器体系
- 拦截器体系是 struts2 的重要组成部分,可以将是 struts2 理解为一个空容器,其中大量的内建拦截器完成类该框架的大部分工作,如解析请求参数、类型转换、将请求参数封装为DTO(Data Transfer Object)、输入验校等,这些内建拦截器可以在 struts.xml 进行配置单独加载,如果将<package>的 extends 属性设置为 "struts-default",则该package会加载常用的默认内建拦截器;
- 在 struts1 中是没有拦截器体系的概念的,所有框架动作逻辑都写在核心控制器中,这样的实现其实带来框架的低灵活性和低拓展性;
以下是一些常用的比较重要的内建拦截器的说明:
完整的内建拦截器列表可以参见
http://struts.apache.org/download.cgi
下载的 document-zip 文档中查询到;
alias | 实现在不同请求中相似参数类别名的转换 |
conversionError | 负责类型转换错误的拦截器 |
createSession | 负责创建一个HttpSession对象 |
debugging | 当struts设置为调试模式时,该拦截器负责提供更多的调试信息 |
execAndWait | 后台执行Action,负责将等待画面发送给用户 |
exception | 负责将异常映射为结果 |
fileUpload | 负责文件上传时解析表单中文本框中的内容 |
i18n | 支持国际化的拦截器,负责将所选的语言、区域信息放置入用户的session中 |
logger | 负责日志记载的拦截器 |
params | 最基本的拦截器,负责解析HTTP请求中的参数,并将该参数值设置为Action的属性值 |
prepare | 如果action实现了prepare()方法,会调用该拦截器的prepare()方法 |
scope | 范围转化拦截器,将Action的状态信息保存在 HttpSession范围,或者 ServletContext范围 |
ServletConfig | 负责 Action 访问 Servlet API |
timer | 输出 Action 的执行时间,常用于分析 Action 性能瓶颈时使用 |
token | 负责阻止重复提交 |
validation | 负责数据验校 |
拦截器的使用
对于已存在的拦截器(包括内建拦截器和自定义拦截器),可以通过在 struts.xml 配置相应的拦截器来进行使用,如示例中显示声明使用“logger”,“timer”拦截器;
<?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>
<constant name="struts.devMode" value="true" />
<package name="default" extends="struts-default">
<action name="test" class="demo.TestAction" method="execute">
<!--显示声明使用内建拦截器-->
<interceptor-ref name="params"/>
<interceptor-ref name="timer" />
<result name="success">/test.jsp</result>
</action>
</package>
</struts>
配置拦截器参数(或覆盖内建拦截器参数)可以使用以下的语法:
<action>
<interceptor-ref name="拦截器名称">
<param name="参数名">参数值</param>
</interceptor-ref>
</action>
配置拦截器的执行顺序
struts 中的拦截器的执行顺序是按照在 struts.xml 中拦截器栈的顺序执行的,可以使用
<interceptor-ref name="defaultStack"> 来指代默认的拦截器栈;
如下示例:
<package name="default" extends="struts-default">
<action name="test" class=".....">
<!--执行默认的拦截器栈-->
<interceptor-ref name="defaultStack" />
<!--执行自定义的拦截器栈-->
<interceptor-ref name="my_interceptor1" />
<!--执行自定义拦截器栈-->
<interceptor-ref name="my_interceptor2" />
<result name="...">...</result>
</action>
以上的示例中,先执行系统默认的拦截器栈,再执行“my_interceptor1”,再执行
“my_interceptor2”;
创建自定义拦截器
要实现一个自定义的拦截器,需要实现一个Interceptor接口,该接口如下,可以直接继承AbstractInterceptor基类来简便实现过程:
public interface Interceptor extends Serializable{
void destroy(); //销毁方法
void init(); //初始化方法
String intercept(ActionInvocation invocation) throws Exception; //拦截方法
}
以下示例实现一个简单的拦截器
import java.util.*;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
public class MyInterceptor extends AbstractInterceptor {
public String intercept(ActionInvocation invocation)throws Exception{
/* let us do some pre-processing */
String output = "Pre-Processing";
System.out.println(output);
/* let us call action or next interceptor */
String result = invocation.invoke();
/* let us do some post-processing */
output = "Post-Processing";
System.out.println(output);
return result;
}
}
在 struts.xml 中调用
<action>
<interceptor-ref name="MyInterceptor" />
</action>