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;
}
所以我们并不建议用上面那两种方法
- 继承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拦截器执行机理如下:
整个结构就如同一个堆栈,除了Action以外,堆栈中的其他元素是Interceptor
Action位于堆栈的底部。由于堆栈"先进后出"的特性,如果我们试图把Action拿出来执行,我们必须首先把位于Action上端的Interceptor拿出来执行。这样,整个执行就形成了一个递归调用
每个位于堆栈中的Interceptor,除了需要完成它自身的逻辑,还需要完成一个特殊的执行职责。这个执行职责有3种选择:
中止整个执行,直接返回一个字符串作为resultCode
通过递归调用负责调用堆栈中下一个Interceptor的执行
如果在堆栈内已经不存在任何的Interceptor,调用Action
struts2拦截器的实现机制的更多相关文章
- 【代码总结】Struts2 拦截器的处理机制
一.什么是拦截器 拦截器是一个类,可以在Action被调用之前和之后执行代码,通常框架的很多功能都是拦截器实现的,如接收输入的参数.数据验证.文件上传等 二.工作方式 做一些Action执行前的预处理 ...
- Struts2拦截器模拟
前言: 接触Struts2已经有一段时间,Student核心内容就是通过拦截器对接Action,实现View层的控制跳转.本文根据自身理解对Struts2进行一个Java实例的模拟,方便大家理解! 示 ...
- 浅谈Struts2拦截器的原理与实现
拦截器与过滤器 拦截器是对调用的Action起作用,它提供了一种机制可以使开发者定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行.同时也是提供了 ...
- 基于SSH2框架Struts2拦截器的登录验证实现(转)
大象在这里假设你已经弄清楚了Struts2拦截器的基本概念,可以进入实际运用了.那么我们在之前的基础上只需要做下小小的改变,就可以使用Struts2的拦截器机制实现登录的验证. 修改数 ...
- Struts2拦截器原理以及实例
一.Struts2拦截器定义 1. Struts2拦截器是在访问某个Action或Action的某个方法,字段之前或之后实施拦截,并且Struts2拦截器是可插拔的,拦截器是AOP的一种实现. 2. ...
- struts2(五)之struts2拦截器与自定义拦截器
前言 前面介绍了struts2的输入验证,如果让我自己选的话,肯定是选择xml配置校验的方法,因为,能使用struts2中的一些校验规则,就无需自己编写了, 不过到后面应该都有其他更方便的校验方法,而 ...
- Struts2拦截器详解
一.Struts2拦截器原理: Struts2拦截器的实现原理相对简单,当请求struts2的action时,Struts 2会查找配置文件,并根据其配置实例化相对的 拦截器对象,然后串成一个列 ...
- 解决Struts2拦截器的对于参数传递无效问题
今天做项目时,使用拦截器对用户权限检查.拦截器本身没有问题,可是实现权限拦截,但是传递的参数全部都无效了.搞了很久,由于对拦截器的内部机制不是特别熟悉,所以重新研读了一下Struts2的拦截器.找到了 ...
- Struts2 拦截器配置以及实现
@(Java ThirdParty)[Struts|Interceptor] Struts2 拦截器配置以及实现 Struts2的拦截器应用于Action,可以在执行Action的方法之前,之后或者两 ...
随机推荐
- IOS之UIColor
转自:http://blog.csdn.net/wudizhukk/article/details/8607229 UIColor常见用法,废话少说 直接网上抄来记录下,凭空想还真有点想不起来,最近记 ...
- windows zlib库编译步骤
下载地址 http://www.zlib.net/ 动态库下载地址 如果自己实在不想编译的,可以直接下载 https://download.csdn.net/download/zhangxuechao ...
- Bootstrap Table列宽拖动的方法
在之前做过的一个web项目中,前端表格是基于jQuery和Bootstrap Table实现的,要求能利用拖动改变列宽,现将实现的过程记录如下: 1. Bootstrap Table可拖动,需要用到它 ...
- Oracle 11g 手工建库
假设数据库软件已经安装好,现在没有图形界面无法用dbca安装数据库,那么用手工建库,数据库名为edw 创建目录 [oracle@localhost ~]$ mkdir -p /u01/app/orac ...
- 【分布式搜索引擎】Elasticsearch之如何安装Elasticsearch
在Macos上安装 一.下载安装过程 最新版本下载地址: https://www.elastic.co/cn/downloads/elasticsearch 历史版本下载地址: https://www ...
- Linux7/Centos7用户密码安全
当Linux7/Centos7的用户root密码常用如下方式找回密码: 第一步:按e键进入内核启动页面如下: 第二步:在linux16一行LANG=zh_CN.UTF-8后面加rd.break con ...
- RabbitMQ的几个常见问题
1. 如何保证消息尽量发送成功? 问题描述: 如果没有启动消费者,重启了RabbitMQ服务,队列和消息都会丢失. 解决方案: 针对这个问题,有以下几个机制可以解决: 生产者确认: 持久化: 手动AC ...
- Codeforces 1278F: Cards
题目传送门:CF1278F. 题意简述: 有 \(n\) 个独立随机变量 \(x_i\),每个随机变量都有 \(p = 1/m\) 的概率取 \(1\),有 \((1-p)\) 的概率取 \(0\). ...
- csp 201709-2 优先队列模拟
数据规模: 用优先队列对各个事件的发生先后记录即可: #include<iostream> #include<queue> using namespace std; ]; st ...
- volatile关键字及Java内存模式
参考文档:https://www.cnblogs.com/_popc/p/6096517.html volatile关键字虽然从字面上理解起来比较简单,但是要用好不是一件容易的事情.它与Java的内存 ...