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的方法之前,之后或者两 ...
随机推荐
- AI 图像识别的测试
随着AI 的浪潮发展,AI 的应用场景越来越广泛,其中计算机视觉更是运用到我们生活中的方方面面.作为一个测试人员,需要紧跟上 AI 的步伐,快速从传统业务测试,转型到 AI 的测试上来.而人脸识别作为 ...
- JavaScript深入浅出第5课:Chrome是如何成功的?
摘要: Chrome改变世界. <JavaScript深入浅出>系列: JavaScript深入浅出第1课:箭头函数中的this究竟是什么鬼? JavaScript深入浅出第2课:函数是一 ...
- element-ui的表单验证this.$refs[formName].validate的代码不执行
经过排查,如果自定义验证中,每种情况都要写明确和有回调函数callback var validatePhone = (rule, value, callback) => { const reg ...
- python通过连接池连接redis,操作redis队列
在每次使用redis都进行连接的话会拉低redis的效率,都知道redis是基于内存的数据库,效率贼高,所以每次进行连接比真正使用消耗的资源和时间还多.所以为了节省资源,减少多次连接损耗,连接池的作用 ...
- XGBoost 完整推导过程
参考: 陈天奇-"XGBoost: A Scalable Tree Boosting System" Paper地址: <https://arxiv.org/abs/1603 ...
- 团队项目-Alpha2版本发布
第五次团队作业 序言 所属课程 https://edu.cnblogs.com/campus/xnsy/2019autumnsystemanalysisanddesign 作业要求 https://w ...
- 面向对象程序设计(Java) 第4周学习指导及要求
2019面向对象程序设计(Java)第4周学习指导及要求(2019.9.17-2019.9. 23) 学习目标 掌握类与对象的基础概念,理解类与对象的关系: 掌握对象与对象变量的关系: 掌握预定义类 ...
- LiunxCentos7 上安装 FastDFS
Centos7 上安装 FastDFS 1.安装gcc(编译时需要) FastDFS是C语言开发,安装FastDFS需要先将官网下载的源码进行编译,编译依赖gcc环境,如果没有gcc环境,需要安装gc ...
- [CODEVS4632][BZOJ4326]运输计划
题目描述 Description 公元 2044 年,人类进入了宇宙纪元.L 国有 n 个星球,还有 n−1 条双向航道,每条航道建立在两个星球之间,这 n−1 条航道连通了 L 国的所有星球.小 P ...
- 前端Vue项目——课程详情页面实现
一.详情页面路由跳转 应用 Vue Router 编程式导航通过 this.$router.push() 来实现路由跳转. 1.绑定查看详情事件 修改 src/components/Course/Co ...