前言

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

开始之前先了解下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

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

  1. 【代码总结】Struts2 拦截器的处理机制

    一.什么是拦截器 拦截器是一个类,可以在Action被调用之前和之后执行代码,通常框架的很多功能都是拦截器实现的,如接收输入的参数.数据验证.文件上传等 二.工作方式 做一些Action执行前的预处理 ...

  2. Struts2拦截器模拟

    前言: 接触Struts2已经有一段时间,Student核心内容就是通过拦截器对接Action,实现View层的控制跳转.本文根据自身理解对Struts2进行一个Java实例的模拟,方便大家理解! 示 ...

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

    拦截器与过滤器           拦截器是对调用的Action起作用,它提供了一种机制可以使开发者定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行.同时也是提供了 ...

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

        大象在这里假设你已经弄清楚了Struts2拦截器的基本概念,可以进入实际运用了.那么我们在之前的基础上只需要做下小小的改变,就可以使用Struts2的拦截器机制实现登录的验证.     修改数 ...

  5. Struts2拦截器原理以及实例

    一.Struts2拦截器定义 1. Struts2拦截器是在访问某个Action或Action的某个方法,字段之前或之后实施拦截,并且Struts2拦截器是可插拔的,拦截器是AOP的一种实现. 2. ...

  6. struts2(五)之struts2拦截器与自定义拦截器

    前言 前面介绍了struts2的输入验证,如果让我自己选的话,肯定是选择xml配置校验的方法,因为,能使用struts2中的一些校验规则,就无需自己编写了, 不过到后面应该都有其他更方便的校验方法,而 ...

  7. Struts2拦截器详解

    一.Struts2拦截器原理: Struts2拦截器的实现原理相对简单,当请求struts2的action时,Struts 2会查找配置文件,并根据其配置实例化相对的    拦截器对象,然后串成一个列 ...

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

    今天做项目时,使用拦截器对用户权限检查.拦截器本身没有问题,可是实现权限拦截,但是传递的参数全部都无效了.搞了很久,由于对拦截器的内部机制不是特别熟悉,所以重新研读了一下Struts2的拦截器.找到了 ...

  9. Struts2 拦截器配置以及实现

    @(Java ThirdParty)[Struts|Interceptor] Struts2 拦截器配置以及实现 Struts2的拦截器应用于Action,可以在执行Action的方法之前,之后或者两 ...

随机推荐

  1. ios开发之--为父view上的子view添加阴影

    项目中碰到一个问题,在tableview的headerview里面有很一个子view,设计师的要求是在下方添加一个阴影,效果如下: 以前的实现思路就是,代码如下: 添加阴影 调用视图的 layer C ...

  2. Android四大组件:BroadcastReceiver 介绍

    介绍 BroadcastReceiver 即广播组件,是 Android 的四大组件之一.用于监听和接收广播消息,并做出响应.有以下一些应用: 不同组件之间的通信(应用内或不同应用之间). 多线程之间 ...

  3. [linux]在使用rsync时需要注意的小细节

    很简单:前一个目录末尾是目录的话,最后是否带/是有区别的. 具体看测试: # usr @ the-pc in ~/cptest02 [2:28:02] $ ll 总用量 0 # usr @ the-p ...

  4. Codeforces Round #304 (Div. 2)(CF546E) Soldier and Traveling(最大流)

    题意 给定 n 个城市,m 条边.人只能从走相邻边相连(只能走一次)的城市. 现在给你初始城市的每一个人数,再给一组每个城市人数.询问是否可以从当前人数变换到给定人数.如果能,输入"YES& ...

  5. C语言的常量

    #include<stdio.h> int main(void) { ; //定义一个常量,不能被修改,可以赋初值:常量的标识符建议使用大写字母 ; //初始化 printf(" ...

  6. day13_7.15 迭代器和生成器

    1.迭代器 迭代就是一个更新换代的过程,每次迭代都必须基于上一次的结果. 迭代器就是迭代取值的工具.举个例子: while True: print('循环输出') 此代码会无限循环输出文字,是个死循环 ...

  7. 通过DatagramSocket实现UDP编程(十三)

    原文链接:https://www.cnblogs.com/hysum/p/7533149.html UDP通信: UDP协议(用户数据报协议)是无连接.不可靠.无序的. UDP协议以数据报作为数据传输 ...

  8. LeetCode 110. Balanced Binary Tree平衡二叉树 (C++)

    题目: Given a binary tree, determine if it is height-balanced. For this problem, a height-balanced bin ...

  9. 了解html

    什么是html? html:Hyper Text Markup Language(超文本标记语言) 纯文本:只能存储一些简单的字符(不能插入图片.视频...) 注意:html不是一种编程语言(它没有任 ...

  10. File.createNewFile和 File.createTempFile比较和区别

    原文地址:http://wzhiju.iteye.com/blog/1119037 最近,在看代码时看到了一个方法, File.createTempFile() ,由此联想到File.createNe ...