一、拦截器简介
为什么需要拦截器
对于任何优秀的MVC框架,都会提供一些通用的操作,如请求数据的封装、类型转换、数据校验、解析上传的文件、防止表单的多次提交等。早期的MVC框架将这些操作都写死在核心控制器中,而这些常用的操作又不是所有的请求都需要实现,这就导致了框架的灵活性不足,可扩展性降低。
Struts2将它的核心功能放到拦截器中实现,而不是几种放在核心控制器中实现,把大部分控制器需要完成的工作按功能分开定义,每个拦截器完成一个功能,而完成这些功能的拦截器可以自由选择、灵活组合,需要哪些拦截器,只要在struts.xml配置文件中指定即可,从而增强了框架的灵活性。
如果有一批拦截器经常固定在一起使用,可以将这些小规模的拦截器定义成为大规模功能的拦截器栈(拦截器栈是根据不同的应用需求定义的拦截器组合)。从结构上看,拦截器栈相当于多个拦截器的组合,而从功能上看,拦截器栈也是拦截器,同样可以与其他拦截器或拦截器栈一起组成更大规模功能的拦截器栈。
拦截器的工作原理
拦截器能够在一个Action执行前后拦截它,类似于Servlet中的过滤器。拦截器围绕着Action和Result的执行而执行,拦截器的工作方式如图

拦截器的实现原理与Servlet过滤器的实现原理差不多,以链式执行,对真正要执行的方法(execute())进行拦截。首先执行Action配置的拦截器,在Action和Result执行之后,拦截器再一次执行(按与先前调用相反的顺序),以此链式执行的过程中,每一个拦截器都可以直接返回,从而中止余下的拦截器、Action及Result的执行。
当ActionInvocation的invoke()方法被调用时,开始执行Action配置的第一个拦截器,invoke()方法总是映射到第一个拦截器,ActionInvocation负责跟踪执行过程的状态,并且把控制器交给合适的拦截器。ActionIncation通过拦截器的intercept()方法将控制转交给拦截器。
拦截器的执行过程可以看作是一个递归的过程,后续拦截器继续执行,最终指向Action,这些都是通过递归调用ActionInvocation的invoke()方法实现的。每个invoke()方法被调用时,ActionInvocation都查询执行状态,调用下一个拦截器,直到最后一个拦截器,invoke()方法会执行Action。
拦截器有三阶段的、有条件的执行周期,过程如下
- 做一些Action执行前的预处理。拦截器可以准备、过滤、改变或者操作任何可以访问的数据,包括Action。
- 调用ActionInvocation的invoke()方法将控制转交给后续的拦截器或者返回结果字符串终止执行。如果拦截器决定请求的处理不应该继续,可以不调用invoke()方法,而是直接返回一个控制字符串,这种方式可以停止后续执行,并且决定哪个结果呈现给客户端。
- 做一些Action执行后的处理。此时,拦截器依然可以改变可以访问的对象和数据,只是此时框架已经选择了一个结果呈现给客户端了
二、 拦截器的配置
配置拦截器
暂时留空
使用拦截器
暂时留空
默认拦截器
暂时留空
内建拦截器
- 内建拦截器的介绍
- 内建拦截器的配置
自定义拦截器
- 实现拦截器类
- 自定义拦截器实例
深入拦截器
- 拦截器的方法过滤
- 使用拦截器实现权限控制