再读Struts2之三:拦截器
Interceptors
拦截器从概念上来讲和Servlet过滤器或者JDK的Proxy类是一样的。它提供了一种对核心组件Action进行预处理和事后处理的功能。
和Servlet过滤器一样,拦截器可以被分层和排序。它还可以访问所执行的Action和所有的环境变量与执行属性。
如果要在Action中激活依赖注入功能(或其他任何由拦截器提供的功能),就必须要对Action进行配置。
和其他元素一样,许多拦截器都已经提供了默认的配置项。你只需要确认一下Action所在的Package继承了“struts-default”package。
在package节点下面,追加如下代码:
<interceptors> <interceptor name="autowiring" class="…xwork2.spring.interceptor.ActionAutowiringInterceptor"/> </interceptors>
我们同时还要确保Action中应用了所需的拦截器。
<action name="my" class="com.fdar.infoq.MyAction" > <result>view.jsp</result> <interceptor-ref name="autowiring"/> </action>
在这种情况下,Action所应用的拦截器是没有数量限制的。但是拦截器的配置顺序必须要和执行的顺序一样。
第二种方式是在当前的Package下面配置一个默认的拦截器,仅能设定一个:
<default-interceptor-ref name="autowiring"/>
拦截器栈
一个请求对应着N个拦截器是很正常的事情,所以会出现拦截器栈。
它能够把我们指定的拦截器组织起来作为一个拦截器栈。
<interceptor-stack name="basicStack"> <interceptor-ref name="exception"/> <interceptor-ref name="servlet-config"/> <interceptor-ref name="prepare"/> <interceptor-ref name="checkbox"/> <interceptor-ref name="params"/> <interceptor-ref name="conversionError"/> </interceptor-stack>
每一个 <interceptor-ref … />标签都引用了在此之前配置的拦截器或者是拦截器栈。
尽管拦截器和拦截器栈不同,但是struts2会对他们一视同仁。也就是说,
<default-interceptor-ref name="autowiring"/> // name可以既设定一个拦截器也可以设定一个拦截器栈
<interceptor-ref name="autowiring"/> // name可以既设定一个拦截器也可以设定一个拦截器栈
定义自己的拦截器
我们只需要实现XWork框架中一个简单的接口就可以定义一个我们自己的拦截器。
其接口如下:
public interface Interceptor extends Serializable { void destroy(); void init(); String intercept(ActionInvocation invocation) throws Exception; }
继承AbstractInterceptor也是一种方式。这个类对“destroy”和“init”方法进行了重写,但在方法中没有执行任何操作。
ActionInvocation 对象可以用来访问
- 运行时环境,以及Action本身;
- 上下文(包括了Web应用的请求参数,session参数,用户Local等等);
- Action的执行结果;还有那些调用Action的方法并判断Action是否已被调用。
至于实现方式,可以参考struts-default.xml中的拦截器们。
其实所有的拦截器都会返回一个string,而这个string正常情况下都是action返回的值。
invocation.invoke(); 方法的作用就是调用下一个拦截器,如果没有下一个拦截器了的话,就直接调用action的方法了。
默认的拦截器的功能基本上如下:
拦截器 |
名字 |
说明 |
Alias Interceptor |
alias |
在不同请求之间将请求参数在不同名字件转换,请求内容不变 |
Chaining Interceptor |
chain |
让前一个Action的属性可以被后一个Action访问,现在和chain类型的result()结合使用。 |
Checkbox Interceptor |
checkbox |
添加了checkbox自动处理代码,将没有选中的checkbox的内容设定为false,而html默认情况下不提交没有选中的checkbox。 |
Cookies Interceptor |
cookies |
使用配置的name,value来是指cookies |
Conversion Error Interceptor |
conversionError |
将错误从ActionContext中添加到Action的属性字段中。 |
Create Session Interceptor |
createSession |
自动的创建HttpSession,用来为需要使用到HttpSession的拦截器服务。 |
Debugging Interceptor |
debugging |
提供不同的调试用的页面来展现内部的数据状况。 |
Execute and Wait Interceptor |
execAndWait |
在后台执行Action,同时将用户带到一个中间的等待页面。 |
Exception Interceptor |
exception |
将异常定位到一个画面 |
File Upload Interceptor |
fileUpload |
提供文件上传功能 |
I18n Interceptor |
i18n |
记录用户选择的locale |
Logger Interceptor |
logger |
输出Action的名字 |
Message Store Interceptor |
store |
存储或者访问实现ValidationAware接口的Action类出现的消息,错误,字段错误等。 |
Model Driven Interceptor |
model-driven |
如果一个类实现了ModelDriven,将getModel得到的结果放在Value Stack中。 |
Scoped Model Driven |
scoped-model-driven |
如果一个Action实现了ScopedModelDriven,则这个拦截器会从相应的Scope中取出model调用Action的setModel方法将其放入Action内部。 |
Parameters Interceptor |
params |
将请求中的参数设置到Action中去。 |
Prepare Interceptor |
prepare |
如果Acton实现了Preparable,则该拦截器调用Action类的prepare方法。 |
Scope Interceptor |
scope |
将Action状态存入session和application的简单方法。 |
Servlet Config Interceptor |
servletConfig |
提供访问HttpServletRequest和HttpServletResponse的方法,以Map的方式访问。 |
Static Parameters Interceptor |
staticParams |
从struts.xml文件中将中的中的内容设置到对应的Action中。 |
Roles Interceptor |
roles |
确定用户是否具有JAAS指定的Role,否则不予执行。 |
Timer Interceptor |
timer |
输出Action执行的时间 |
Token Interceptor |
token |
通过Token来避免双击 |
Token Session Interceptor |
tokenSession |
和Token Interceptor一样,不过双击的时候把请求的数据存储在Session中 |
Validation Interceptor |
validation |
使用action-validation.xml文件中定义的内容校验提交的数据。 |
Workflow Interceptor |
workflow |
调用Action的validate方法,一旦有错误返回,重新定位到INPUT画面 |
Parameter Filter Interceptor |
N/A |
从参数列表中删除不必要的参数 |
Profiling Interceptor |
profiling |
通过参数激活profile |
拦截器与过滤器的区别 :
- 拦截器是基于java的反射机制的,而过滤器是基于函数回调。
- 拦截器不依赖与servlet容器,过滤器依赖与servlet容器。
- 拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
- 拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。
- 在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次
执行顺序 :
过滤前 - 拦截前 - Action处理 - 拦截后 - 过滤后。个人认为过滤是一个横向的过程,首先把客户端提交的内容进行过滤(例如未登录用户不能访问内部页面的处理);过滤通过后,拦截器将检查用户提交数 据的验证,做一些前期的数据处理,接着把处理后的数据发给对应的Action;Action处理完成返回后,拦截器还可以做其他过程(还没想到要做啥), 再向上返回到过滤器的后续操作。
以上引用自:http://blog.csdn.net/oypj2010/article/details/7260556;