Struts2的interceptor

从软件架构的角度讲:拦截器属于AOP编程的范畴。它将影响了多个业务对象的公共行为封装到一个个可重用的模块,减少了系统的重复代码,实现功能的高度内聚,确保了业务对象                             的整洁和纯度。

从java代码的角度讲:它就是一个普度的Java对象,它只需要实现一个名为Interceptor的接口。

当我们在struts.xml配置文件中包含struts-default包时,我们就会拥有默认的拦截器和拦截器栈。一个拦截器栈包含一组拦截器。堆栈中的每个拦截器使用interceptor-ref元素定义。

拦截器的工作原理:

当框架接收到一个请求的时候,它首先必须决定这个URL映射到哪一个动作组件。这个动作组件的一个实例就会被加入到一个新创建的ActionInvocation实例中。接着框架咨询声明性架构(XML配置文件或Java注解),以发现哪一些拦截器应该被触发,以及按照什么样的顺序触发。将这些拦截器的引用添加到ActionInvocation中。除了这些核心元素,ActionInvocation也拥有其他重要的信息(Servlet请求对象和当前动作组件可用的结果组件列表)。

当ActionInvocation被创建完毕,并且填充了需要的所有对象和信息,就可以被使用了。ActionInvocation公开了一个invoke()方法,框架通过调用这个方法开始动作的执行。当框架调用了这个方法时,ActionInvocation通过执行拦截器栈中的第一个拦截器开始这个调用过程。需要注意的是,invoke()并不是总是指向拦截器栈的第一个拦截器,ActionInvocation负责跟踪执行过程达到的状态,并且把控制交给栈中合适的拦截器(通过调用拦截器的intercept()方法将控制权交给拦截器)。通过递归调用(递归过程?框架通过第一次调用ActionInvocation对象的invoke()方法开始了这个过程。ActionInvocation通过调用拦截器的intercept()方法把控制权交给第一个拦截器。重要的是,intercept()方法把ActionInvocation实例作为一个参数。在拦截器的处理过程中,他会调用ActionInvocation实例参数的invoke()方法来继续调用后续拦截器的递归过程。因此,在通常的执行中,调用过程向下通过所有拦截器,直到栈中再也没有拦截器时,触发动作。另外,ActionInvocation在内部管理处理状态,因此它总是直到自己现在处在栈的什么位置。)ActionInvocation的invoke()方法,拦截器栈中后续的拦截器继续执行,最终执行动作。这是因为每一次invoke()方法被调用时,ActionInvocation都会查询自身的状态,调用接下来的拦截器。在所有拦截器都被调用之后,invoke()方法会促使动作类执行。

执行顺序:

在提交数据到框架时,框架调用拦截器的过程,首先框架会根据URL请求创建指定的动作TestAction,将TestAction的实例和TestAction相关的拦截器引用myStack放入一个新的ActionInvocation对象中(还包含其他信息),然后框架调用ActionInvocation的invoke()方法,此时开始了拦截器栈调用过程,最开始调用拦截器栈的第一个拦截器也就是Intercept1,拦截器执行完预处理后,因为intercept()方法接收一个ActionInvocation对象作为参数,在Intercept1.intercept()方法中继续调用 ActionInvocation对象的invoke()方法将向下继续调用栈中余下的拦截器Intercept2...一直到栈中没有拦截器为止,最后执行动作组件。在结果被呈现之后,拦截器会按照相反的顺序再触发一遍,使他们可以进行后处理。

拦截器工作原理图:

拦截器触发时能够做些什么?

1. 做一些预处理。在这个阶段拦截器可以用来准备、过滤、改变或者操作任何可以访问的重要数据。这些数据包括所有与当前请求相关的关键对象和数据,也包括动作。

2. 通过调用invoke()方法将控制转移给后续的拦截器,直到动作。或者通过返回一个控制字符串中断执行。在这个阶段,如果拦截器决定请求不应该继续,他可以不调用ActionInvocation实例上的invoke()方法,而是直接返回一个控制字符串。通过这种方式可以停止后续的执行,并且决定哪个结果被呈现。

3. 做一些后加工。在这个阶段,任何一个返回的拦截器可以修改可以访问的对象的数据作为后加工,但是此时结果已经确定了。

查看dtd文档可以看到interceptors标签要定义在package标签下,我们对照struts-default.xml可以看到interceptors标签确实定义在package标签下,并且在dtd文档中package元素右边说明中interceptors标签右边带有一个"?"符号,表示该标签要么有且只有1个,要么没有

再接着查看dtd文档interceptors元素右面有"(interceptor|interceptor-stack)*"的一串字符式子,表示interceptors标签下可以有0个或多个interceptor标签和interceptor-stack标签,并且不分顺序

在dtd文档中可以看到interceptor-stack的name属性为#REQUIRED表示这是必须的属性,你声明一个拦截器栈必须给栈取一个名字。而interceptor标签中有两个属性name和class它们都是#REQUIRED,所以你想定义一个拦截器就必须指明这两个属性的值,name为拦截器的名字,class为这个拦截器会使用哪一个类作为它的处理器。还有interceptor-stack标签可以包含许多interceptor-ref标签,这些标签是用于引用你使用interceptor标签声明的拦截器另外的拦截器栈,它的name属性的值为interceptor标签声明的拦截器的name值或其他拦截器栈的name值,该属性也是#REQUIRED。

最后一个package可以定义一组默认拦截器(有且只能有1个,dtd规定) ,例如在struts-default.xml文档中

<default-interceptor-ref name="defaultStack"/>

定义了默认的拦截器组,这个默认的拦截器组会与这个包内没有显示声明自己的拦截器的所有动作相关联。

下面为Struts 2为我们提供的struts-default.xml文件部分:

  1 <struts>
  2         ...
  3         <interceptors>
  4             <interceptor name="alias" class="com.opensymphony.xwork2.interceptor.AliasInterceptor"/>
  5             <interceptor name="autowiring" class="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor"/>
  6             <interceptor name="chain" class="com.opensymphony.xwork2.interceptor.ChainingInterceptor"/>
  7             <interceptor name="conversionError" class="org.apache.struts2.interceptor.StrutsConversionErrorInterceptor"/>
  8             <interceptor name="cookie" class="org.apache.struts2.interceptor.CookieInterceptor"/>
  9             <interceptor name="clearSession" class="org.apache.struts2.interceptor.ClearSessionInterceptor"/>
 10             <interceptor name="createSession" class="org.apache.struts2.interceptor.CreateSessionInterceptor"/>
 11             <interceptor name="debugging" class="org.apache.struts2.interceptor.debugging.DebuggingInterceptor"/>
 12             <interceptor name="execAndWait" class="org.apache.struts2.interceptor.ExecuteAndWaitInterceptor"/>
 13             <interceptor name="exception" class="com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor"/>
 14             <interceptor name="fileUpload" class="org.apache.struts2.interceptor.FileUploadInterceptor"/>
 15             <interceptor name="i18n" class="com.opensymphony.xwork2.interceptor.I18nInterceptor"/>
 16             <interceptor name="logger" class="com.opensymphony.xwork2.interceptor.LoggingInterceptor"/>
 17             <interceptor name="modelDriven" class="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor"/>
 18             <interceptor name="scopedModelDriven" class="com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor"/>
 19             <interceptor name="params" class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/>
 20             <interceptor name="actionMappingParams" class="org.apache.struts2.interceptor.ActionMappingParametersInteceptor"/>
 21             <interceptor name="prepare" class="com.opensymphony.xwork2.interceptor.PrepareInterceptor"/>
 22             <interceptor name="staticParams" class="com.opensymphony.xwork2.interceptor.StaticParametersInterceptor"/>
 23             <interceptor name="scope" class="org.apache.struts2.interceptor.ScopeInterceptor"/>
 24             <interceptor name="servletConfig" class="org.apache.struts2.interceptor.ServletConfigInterceptor"/>
 25             <interceptor name="timer" class="com.opensymphony.xwork2.interceptor.TimerInterceptor"/>
 26             <interceptor name="token" class="org.apache.struts2.interceptor.TokenInterceptor"/>
 27             <interceptor name="tokenSession" class="org.apache.struts2.interceptor.TokenSessionStoreInterceptor"/>
 28             <interceptor name="validation" class="org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor"/>
 29             <interceptor name="workflow" class="com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor"/>
 30             <interceptor name="store" class="org.apache.struts2.interceptor.MessageStoreInterceptor"/>
 31             <interceptor name="checkbox" class="org.apache.struts2.interceptor.CheckboxInterceptor"/>
 32             <interceptor name="profiling" class="org.apache.struts2.interceptor.ProfilingActivationInterceptor"/>
 33             <interceptor name="roles" class="org.apache.struts2.interceptor.RolesInterceptor"/>
 34             <interceptor name="jsonValidation" class="org.apache.struts2.interceptor.validation.JSONValidationInterceptor"/>
 35             <interceptor name="annotationWorkflow" class="com.opensymphony.xwork2.interceptor.annotations.AnnotationWorkflowInterceptor"/>
 36             <interceptor name="multiselect" class="org.apache.struts2.interceptor.MultiselectInterceptor"/>
 37
 38             <!-- Basic stack -->
 39             <interceptor-stack name="basicStack">
 40                 <interceptor-ref name="exception"/>
 41                 <interceptor-ref name="servletConfig"/>
 42                 <interceptor-ref name="prepare"/>
 43                 <interceptor-ref name="checkbox"/>
 44                 <interceptor-ref name="multiselect"/>
 45                 <interceptor-ref name="actionMappingParams"/>
 46                 <interceptor-ref name="params">
 47                     <param name="excludeParams">dojo\..*,^struts\..*</param>
 48                 </interceptor-ref>
 49                 <interceptor-ref name="conversionError"/>
 50             </interceptor-stack>
 51
 52             <!-- Sample validation and workflow stack -->
 53             <interceptor-stack name="validationWorkflowStack">
 54                 <interceptor-ref name="basicStack"/>
 55                 <interceptor-ref name="validation"/>
 56                 <interceptor-ref name="workflow"/>
 57             </interceptor-stack>
 58
 59             <!-- Sample JSON validation stack -->
 60             <interceptor-stack name="jsonValidationWorkflowStack">
 61                 <interceptor-ref name="basicStack"/>
 62                 <interceptor-ref name="validation">
 63                     <param name="excludeMethods">input,back,cancel</param>
 64                 </interceptor-ref>
 65                 <interceptor-ref name="jsonValidation"/>
 66                 <interceptor-ref name="workflow"/>
 67             </interceptor-stack>
 68
 69             <!-- Sample file upload stack -->
 70             <interceptor-stack name="fileUploadStack">
 71                 <interceptor-ref name="fileUpload"/>
 72                 <interceptor-ref name="basicStack"/>
 73             </interceptor-stack>
 74
 75             <!-- Sample model-driven stack  -->
 76             <interceptor-stack name="modelDrivenStack">
 77                 <interceptor-ref name="modelDriven"/>
 78                 <interceptor-ref name="basicStack"/>
 79             </interceptor-stack>
 80
 81             <!-- Sample action chaining stack -->
 82             <interceptor-stack name="chainStack">
 83                 <interceptor-ref name="chain"/>
 84                 <interceptor-ref name="basicStack"/>
 85             </interceptor-stack>
 86
 87             <!-- Sample i18n stack -->
 88             <interceptor-stack name="i18nStack">
 89                 <interceptor-ref name="i18n"/>
 90                 <interceptor-ref name="basicStack"/>
 91             </interceptor-stack>
 92             ...
 93
 94        </interceptors>
 95
 96         <default-interceptor-ref name="defaultStack"/>
 97
 98         <default-class-ref class="com.opensymphony.xwork2.ActionSupport"/>
 99     </package>
100
101 </struts>

如何定义拦截器:实现Interceptor接口;创建自定义的拦截器还可以扩展com.opensymphony.xwork2.interceptor.AbstractInterceptor类,它并没有什么高级的地方,它仅仅只是帮我们实现了Interceptor接口,帮我们默认实现了init()和destory()方法

下面演示一个简单的权限验证的例子:

它的工作原理很简单,当一个请求访问一个安全动作时,我们想检查请求是否是一个通过身份验证的用户发出的。

权限认证拦截器:

 1 public class AuthenticationInterceptor implements Interceptor
 2 {
 3     private static final long serialVersionUID = -1500368808387165682L;
 4
 5     public void destroy()
 6     {
 7
 8     }
 9
10     public void init()
11     {
12
13     }
14
15     public String intercept(ActionInvocation invocation) throws Exception
16     {
17         Map<String , Object> session = invocation.getInvocationContext().getSession();
18
19         User user = (User) session.get("USER");
20
21         if (user == null)
22         {
23             return Action.INPUT;
24         }
25         else
26         {
27             Action action = (Action) invocation.getAction();
28             if (action instanceof UserAware)
29             {
30                 ((UserAware) action).setUser(user);
31             }
32         }
33
34         return invocation.invoke();
35     }
36 }

最后,Struts 2内置了很多的日常Web开发都会用到的拦截器,所以一般不太需要自己开发一个拦截器,内置的拦截器几乎包含了所有日常需要的功能,要想真正运用好Struts 2必须要了解他们的工作原理,在Struts 2的官方网站上有详细的介绍,可以去哪里找到你需要的东西。

参考文献:

http://www.cnblogs.com/suxiaolei/archive/2011/10/28/2228063.html

时间: 2024-10-15 19:03:22

Struts2的interceptor的相关文章

struts2自定义Interceptor拦截器

1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <!DOCTYPE html> 4 <html> 5 <head> 6 <meta charset="UTF-8"> 7 <title>struts2的一个例子</t

struts2—过滤器interceptor

1.最简单的过滤器 配置文件 <struts> <package name="interceptor" namespace="/interceptor" extends="struts-default"> <interceptors> <!--1. 注册拦截器 --> <interceptor name="iterceptorDemo" class="cn.int

struts2 拦截器(interceptor)

配置主要在struts.xml <!-- 拦截器 --> <interceptors> <interceptor name="default" class="com.formwork.struts2.DefaultIntecetor"></interceptor> <!-- 栈拦截器 --> <interceptor-stack name=""> <intercepto

Struts2原理及简单实例

参考连接: http://blog.csdn.net/laner0515/article/details/27692673/ http://www.cnblogs.com/sobne/articles/5443114.html 一.Struts2原理 设计目标 Struts设计的第一目标就是使MVC模式应用于web程序设计.在这儿MVC模式的好处就不在提了. 技术优势 Struts2有两方面的技术优势,一是所有的Struts2应用程序都是基于client/server HTTP交换协议,The 

Struts2 核心流程

1.Struts2架构图  这是Struts2官方站点提供的Struts 2 的整体结构.  执行流程图 2.Struts2部分类介绍  这部分从Struts2参考文档中翻译就可以了. ActionMapper         ActionMapper其实是HttpServletRequest和Action调用请求的一个映射,它屏蔽了Action对于Request等 java Servlet类的依赖.Struts2中它的默认实现类是DefaultActionMapper,ActionMapper

Struts2(二):工作原理

struts可查看源码:https://github.com/apache/struts 在学习struts2之前,我先看了一些比较早版本对struts2的工作原理相关的介绍,顺便抄写过来,用来帮助自己要弄清这个框架的工作原理. struts2.1.3之前使用的FilterDispatcher,之后的版本使用StrutsPrepareAndExecuteFilter,而我这里还是以Dispatcher为例来记录的. 依据: Since Struts 2.1.3, use org.apache.s

Struts2的action解读

从职责上讲,Control层需要完成以下的职责: 1. 接收从Web容器传递过来的参数,并做恰当的类型转化 2. 调用逻辑处理 3. 搜集数据,并返回到视图 这个其中的第一步和第三步,都离不开Web容器中的对象的处理.而Struts2这个框架和传统框架区别之处在于Struts2中的Action,并不需要依赖于特定的Web容器.我们看不到类似HttpServletRequest,HttpServletResponse等Web容器相关的对象. 虽然Struts2的Action只是一个非常普通的Jav

struts2的核心和工作原理

在学习struts2之前,首先我们要明白使用struts2的目的是什么?它能给我们带来什么样的好处? 设计目标 Struts设计的第一目标就是使MVC模式应用于web程序设计.在这儿MVC模式的好处就不在提了. 技术优势 Struts2有两方面的技术优势,一是所有的Struts2应用程序都是基于client/server HTTP交换协议,The Java Servlet API揭示了Java Servlet只是Java API的一个很小子集,这样我们可以在业务逻辑部分使用功能强大的Java语言

Struts2框架基本使用

时间:2017-1-6 16:53 修改struts.xml配置文件不需要重启服务器. Struts2框架 一.        *   介绍Struts2        *   关于Struts2配置(关于Action配置)        *   关于Struts2结果类型    二.        *   Struts2处理请求参数        *   Struts2的类型转换(了解)        *   Struts2的校验    三.        *   Struts2的国际化