struts2拦截器的实现机制

前言

最近老大让每周写一篇技术性的博客,想想也没啥写,就想着随便拿个以前的项目去研究研究五大框架的底层代码。本人水平有限,有不对的地方还望大家勿喷,指正!

开始之前先了解下strtus2的工作流程:

工作原理图:

(1) 客户端(Client)向Action发用一个请求(Request)

(2) Container通过web.xml映射请求,并获得控制器(Controller)的名字

(3) 容器(Container)调用控制器(StrutsPrepareAndExecuteFilter或FilterDispatcher)。在Struts2.1以前调用FilterDispatcher,Struts2.1以后调用StrutsPrepareAndExecuteFilter

(4) 控制器(Controller)通过ActionMapper获得Action的信息

(5) 控制器(Controller)调用ActionProxy

(6) ActionProxy读取struts.xml文件获取action和interceptor stack的信息。

(7) ActionProxy把request请求传递给ActionInvocation

(8) ActionInvocation依次调用action和interceptor

(9) 根据action的配置信息,产生result

(10) Result信息返回给ActionInvocation

(11) 产生一个HttpServletResponse响应

(12) 产生的响应行为发送给客服端。

拦截器所涉及的接口和类:

用struts2实现拦截器有三种方式:

   1.实现Interceptor接口

    public interface Interceptor
    extends Serializable
    //继承Serializable
{
    public abstract void destroy();
    public abstract void init();
    //ActionInvocation 是一个接口
    public abstract String intercept(ActionInvocation actioninvocation)
        throws Exception;
}

2.继承AbstractInterceptor类

    public abstract class AbstractInterceptor
    implements Interceptor
    //并没有具体实现
{
  public AbstractInterceptor()
    {
    }
    public void init()
    {
    }
    public void destroy()
    {
    }
    public abstract String intercept(ActionInvocation actioninvocation)
        throws Exception;
}

所以我们并不建议用上面那两种方法

  1. 继承MethodFilterInterceptor类

       public abstract class MethodFilterInterceptor extends AbstractInterceptor
    {
        public MethodFilterInterceptor()
        {
            log = LoggerFactory.getLogger(getClass());
            excludeMethods = Collections.emptySet();
            includeMethods = Collections.emptySet();
        }
        public void setExcludeMethods(String excludeMethods)
        {
            this.excludeMethods = TextParseUtil.commaDelimitedStringToSet(excludeMethods);
        }
        public Set getExcludeMethodsSet()
        {
            return excludeMethods;
        }
        public void setIncludeMethods(String includeMethods)
        {
            this.includeMethods = TextParseUtil.commaDelimitedStringToSet(includeMethods);
        }
        public Set getIncludeMethodsSet()
        {
            return includeMethods;
        }
        public String intercept(ActionInvocation invocation)
            throws Exception
        {
            if(applyInterceptor(invocation))
                return doIntercept(invocation);
            else
                return invocation.invoke();
        }
       protected boolean applyInterceptor(ActionInvocation invocation)
        {
           //ActionInvocation将Web页面中的输入元素封装为一个(请求)数据对象”,这个对象就是ActionInvocation类型.
            String method = invocation.getProxy().getMethod();
            boolean applyMethod = MethodFilterInterceptorUtil.applyMethod(excludeMethods, includeMethods, method);
            if(log.isDebugEnabled() && !applyMethod)
                log.debug((new StringBuilder()).append("Skipping Interceptor... Method [").append(method).append("] found in exclude list.").toString(), new String[0]);
            return applyMethod;
        }
        protected abstract String doIntercept(ActionInvocation actioninvocation)
            throws Exception;
        protected transient Logger log;
        //排除的方法集合
        protected Set excludeMethods;
        //包括的方法集合(就是要拦截的方法)
        protected Set includeMethods;
    }

    如上图:

    在执行Action的前后都有拦截器的执行,每个拦截器类的doIntercept(ActionInvocation actionInvocation)方法都会传入一个参数ActionInvocation actionInvocation并且最后一句代码都是return invocation.invoke(),这句代码调用的是DefaultActionInvocation类的invoke方法,而在这个方法里面又会去调用其他的拦截器,这样的话就形成了一个类似递归的递归调用。

    上面的这两张图说明了用拦截器时配置文件的基本配法。

    下面用debug的方式跟下代码:

总结

Struts2拦截器执行机理如下:

  1. 整个结构就如同一个堆栈,除了Action以外,堆栈中的其他元素是Interceptor
  2. Action位于堆栈的底部。由于堆栈"先进后出"的特性,如果我们试图把Action拿出来执行,我们必须首先把位于Action上端的Interceptor拿出来执行。这样,整个执行就形成了一个递归调用
  3. 每个位于堆栈中的Interceptor,除了需要完成它自身的逻辑,还需要完成一个特殊的执行职责。这个执行职责有3种选择:

1) 中止整个执行,直接返回一个字符串作为resultCode

2) 通过递归调用负责调用堆栈中下一个Interceptor的执行

3) 如果在堆栈内已经不存在任何的Interceptor,调用Action

原文地址:https://www.cnblogs.com/nnxud/p/8998008.html

时间: 2024-10-21 02:26:15

struts2拦截器的实现机制的相关文章

【SSH2(实践篇)】--Struts2拦截器精解

上篇博客对Struts2的体系结构做了初步的了解,Struts2是以WebWork作为处理核心,并采用拦截器的机制来处理用户的请求,同时它还集成了Struts1丰富的标签库.另外上篇博客还对Struts2的配置使用进行了初步的介绍,下面将会集中讨论Struts2的拦截器. 一.拦截器 1.拦截器小介 拦截器的功能类似于web.xml文件中的Filter,能对用户的请求进行拦截,通过拦截用户的请求来实现对页面的控制.拦截器是在Struts-core-2.2.3.jar中进行配置的,原始的拦截器是在

解决Struts2拦截器的对于参数传递无效问题

今天做项目时,使用拦截器对用户权限检查.拦截器本身没有问题,可是实现权限拦截,但是传递的参数全部都无效了.搞了很久,由于对拦截器的内部机制不是特别熟悉,所以重新研读了一下Struts2的拦截器.找到了原因:给一个Acton配置一个自定义拦截器后,此action就无法使用框架默认的拦截器栈了,这就导致前后台数据传输无效.解决方法一般有两种: 一.显示的使用默认拦截器 View Row Code 1 <action name="enterSystem_*" class="e

浅谈Struts2拦截器的原理与实现

拦截器与过滤器           拦截器是对调用的Action起作用,它提供了一种机制可以使开发者定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行.同时也是提供了一种可以提取action中可重用的部分的方式,很多业务逻辑都是靠拦截实现的,比如校验,验证登录权限(比如下载时跳转到登陆页面)等等.     过滤器是对整个的请求过程起作用!换句话说就是拦截器没有过滤器的范围广.过滤器是在java web中,你传入的request,response提前过滤掉一些信息

Struts2整理-----Struts2拦截器

struts2的拦截器是struts2的核心,其底层实现使用了Java的反射机制与动态代理. 实现struts2拦截器的方法 1.实现Interceptor接口,实现init(),destory(),intercept()方法. 2.继承AbstractInterceptor类,重写intercept()方法. 3.继承MethodFilterInterceptor类,重写doIntercept()方法 拦截器实现原理: 当请求struts2的action时,strus2会查找配置文件,并根据其

Struts2拦截器原理以及实例

Struts2拦截器原理以及实例 一.Struts2拦截器定义 1. Struts2拦截器是在访问某个Action或Action的某个方法,字段之前或之后实施拦截,并且Struts2拦截器是可插拔的,拦截器是AOP的一种实现. 2. 拦截器栈(Interceptor Stack).Struts2拦截器栈就是将拦截器按一定的顺序联结成一条链.在访问被拦截的方法或字段时,Struts2拦截器链中的拦截器就会按其之前定义的顺序被调用. 二.实现Struts2拦截器原理 Struts 2的拦截器实现相对

Struts2.x教程(三) Struts2拦截器

一.Struts2拦截器介绍 Struts2拦截器是使用AOP实现的,主要是针对action对象进行拦截,可以在访问action的某个方法.字段之前或之后实施拦截. 可以为action配置多个拦截器,Struts2会将这一组拦截器按照一定顺序组织成一个拦截器栈.action可以直接引用某个拦截器栈来实现配置多个拦截器的目的. 对于继承struts_default的package中的action,都会默认引用name=defaultStack的拦截器栈(在struts_default中定义了Str

基于SSH2框架Struts2拦截器的登录验证实现(转)

大象在这里假设你已经弄清楚了Struts2拦截器的基本概念,可以进入实际运用了.那么我们在之前的基础上只需要做下小小的改变,就可以使用Struts2的拦截器机制实现登录的验证. 修改数据库 在user表中增加password字段,将初始密码都设为123,因为是示例所以采用明码,实际开发中,当然不能这样做,需要进行加密处理.再将name改为username,其实name字段可以不用改名,我这样做是为了命名规范,请注意,如果字段改为username,User类中的对应属性也要进行相应变化(如果你加注

Struts2 拦截器(Interceptor )原理和配置

一.Struts2拦截器原理: Struts2拦截器的实现原理相对简单,当请求struts2的action时,Struts 2会查找配置文件,并根据其配置实例化相对的    拦截器对象,然后串成一个列表,最后一个一个地调用列表中的拦截器. 比如:应用要求用户登陆,且必须为指定用户名才可以查看系统中某个视图资源:否则,系统直接转入登陆页面.对于上面的需求,可以在每个Action的执行实际处理逻辑之前,先执行权限检查逻辑,但这种做法不利于代码复用.因为大部分Action里的权限检查代码都大同小异,故

Struts2拦截器概述

--------------------siwuxie095 Struts2 拦截器概述 1.Struts2 框架封装的很多功能都在 Struts2 的拦截器中 2.Struts2 框架中有很多拦截器,但这些拦截器不是每次 都执行,只有默认拦截器才会每次都执行 3.Struts2 默认拦截器的位置 「注意:默认拦截器中也有很多拦截器」 4.拦截器的执行 在 Action 对象创建之后,在 Action 方法执行之前 [made by siwuxie095]