再读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 对象可以用来访问

  1. 运行时环境,以及Action本身;
  2. 上下文(包括了Web应用的请求参数,session参数,用户Local等等);
  3. 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调用ActionsetModel方法将其放入Action内部。

Parameters Interceptor

params

将请求中的参数设置到Action中去。

Prepare Interceptor

prepare

如果Acton实现了Preparable,则该拦截器调用Action类的prepare方法。

Scope Interceptor

scope

Action状态存入sessionapplication的简单方法。

Servlet Config Interceptor

servletConfig

提供访问HttpServletRequestHttpServletResponse的方法,以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

调用Actionvalidate方法,一旦有错误返回,重新定位到INPUT画面

Parameter Filter Interceptor

N/A

从参数列表中删除不必要的参数

Profiling Interceptor

profiling

通过参数激活profile

拦截器与过滤器的区别

  1. 拦截器是基于java的反射机制的,而过滤器是基于函数回调。
  2. 拦截器不依赖与servlet容器,过滤器依赖与servlet容器。
  3. 拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
  4. 拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。
  5. 在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次

执行顺序

  过滤前 - 拦截前 - Action处理 - 拦截后 - 过滤后。个人认为过滤是一个横向的过程,首先把客户端提交的内容进行过滤(例如未登录用户不能访问内部页面的处理);过滤通过后,拦截器将检查用户提交数 据的验证,做一些前期的数据处理,接着把处理后的数据发给对应的Action;Action处理完成返回后,拦截器还可以做其他过程(还没想到要做啥), 再向上返回到过滤器的后续操作。

以上引用自:http://blog.csdn.net/oypj2010/article/details/7260556;

原文地址:https://www.cnblogs.com/voctrals/p/3032917.html