Struts2(4):拦截器

一、拦截器的概念
类似于Servlet里边的过滤器,拦截器是用来拦截器请求的。拦截器实质上是Struts2的核心之一。
拦截器与过滤器区别
1.过滤器可以过滤所有的请求(页面,Servlet),拦截器只能拦截Action请求,不能拦截器页面。
2.拦截器不需要依赖Servlet容器,过滤器需要依赖Servlet容器(需要有servlet的api)

struts2内置的拦截器
在这里插入图片描述

自定义拦截器
方法一:实现Interceptor接口,重写init、interceptor、destory方法(了解)
方法二:继承AbstractInterceptor父类,重写interceptor方法(重点).
方法三:继承MethodFilterInterceptor,重写doInterceptor方法

第二种和第三种方式的区别:
通过第三种方式可以指定拦截某些方法,不拦截某些方法,比较灵活。通过观察MethodFilterInterceptor类的源码可以发现,该拦截器类有两个参数,可以指定拦截哪些方法,不拦截哪些方法。
在这里插入图片描述

配置自定义拦截器(重点):
1.局部拦截器配置,只针对某个action有效
a.在strut.xml文件中声明自定义拦截器
在这里插入图片描述
b.在某个action节点下配置拦截器,指定该action经过哪些拦截器
在这里插入图片描述
注意:先配置的拦截器先经过.

2.全局拦截器配置,针对包下所有的Action都有效
1、在strut.xml文件中声明自定义拦截器,同局部的声明拦截器的方式
在这里插入图片描述
2、自定义拦截器栈(采用节点),引入自定义拦截器,同时也要引入默认的栈
在这里插入图片描述
3、让package使用自定义的拦截器栈,使用节点
在这里插入图片描述

注意:
1.可以在拦截器里改变正常流程
在Test1Interceptor拦截器中改变正常流程。修改Test1Interceptor类,不要调用invoke方法,直接返回fail.
在这里插入图片描述

2.指定不要拦截某些请求或指定只拦截某些请求,只能继承MethodFilterInterceptor,指定参数excludeMethods或includeMethods.
需求:默认情况下,test2请求会经过test1Interceptor,test2Interceptor,test3Interceptor,现在我不想让test2请求经过test3Interceptor,可以给test3Interceptor添加一个参数excludeMethods,只要是在这个集合里的方法,一律不拦截.

在这里插入图片描述

拦截器的应用: 登录验证、日志的记录、权限的验证.

Struts2底层运行原理分析
在这里插入图片描述
原理分析:
1、服务器启动前完成核心过滤器的初始化,包括加载struts.xml,进行预处理(参考StrutsPrepareAndExecuteFilter代码57行,InitOperations第74行,ispatcher第464行)
在这里插入图片描述
2、请求进来时,执行doFilter方法过滤请求,找到该请求对应的mapping(参考过滤器第92行)
3、如果mapping为null,则直接过滤. 使用chain.doFilter()方法,放行。忽略所有的拦截器和action,直接响应;
如果mapping不为null,执行action(参考过滤器第99行代码).
在这里插入图片描述

4、在执行action时,需要为action增强功能,调用serviceAction方法,为action服务(参考ExecuteOperations类第81行代码)
5、在serviceAction方法中,通过创建ActionProxy(代理)来增强action的功能(参考Dispatcher类第554,555行代码)
在这里插入图片描述

a)在创建代理前,创建ActionInvocation对象,相当于一个“调度”,安排接下来的流程(参考DefaultActionProxyFactory类代码第56行,在创建代理时,时通过DefaultActionProxyFactory来创建的)
b)接着,调用代理对象的prepare方法完成准备工作(参考DefaultActionProxyFactory的第70行代码),主要是调用调度对象的init方法完成调度的初始化(参考DefaultActionProxy的第194行代码)
c)在初始化调度器时,获取到action需要经过的拦截器集合(参考DefaultActionInvocation的第406,407行代码)
在这里插入图片描述
6、完成准备工作后,调用代理对象的execute方法完成功能的增强(参考Dispatcher的第564行代码),具体是调用调度对象的invoke方法,安排接下来的流程(参考DefaultActionProxy的第147行代码)
7、在调度器中,遍历拦截器,依次调用,直到最后调用action(参考DefaultActionInvocation的第239-251行代码)
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/tangiwang/article/details/89715040
今日推荐