Spring MVC_拦截器
三要素
- 拦截
- 过滤
- 放行
程序测试
1、准备工作
导入 jar 包
commons-logging-1.1.3.jar
spring-aop-4.0.0.RELEASE.jar
spring-beans-4.0.0.RELEASE.jar
spring-context-4.0.0.RELEASE.jar
spring-core-4.0.0.RELEASE.jar
spring-expression-4.0.0.RELEASE.jar
spring-web-4.0.0.RELEASE.jar
spring-webmvc-4.0.0.RELEASE.jar
在web.xml
中配置前端控制器 DispatcherServlet 并指定 spring-mvc 的配置文件
创建 spring-mvc 的配置文件spring-mvc.xml
,配置自动扫描的包并配置视图解析器
2、方法一
① 实现 HandlerInterceptor 接口
[1]preHandle()方法
签名:boolean preHandle(HttpServletRequest, HttpServletResponse, Object)
在执行目标 handler 方法之前执行,如果返回 true,则继续执行后续拦截器和目标 handler 方法;如果返回 false 则不执行。
注意:返回 false 时最好借助转发或重定向等方式为客户端提供一个响应页面。
[2]postHandle()方法
签名:void postHandle(HttpServletRequest, HttpServletResponse, Object, ModelAndView)
在执行目标 handler 方法之后、渲染视图之前执行。
[3]afterCompletion()方法
在渲染视图之后、返回响应之前执行。
1 | public class PrivateInterceptor implements HandlerInterceptor { |
② 配置拦截器
在spring-mvc.xml
配置文件中配置拦截器类
1 | <!-- 配置拦截器 --> |
3、方法二
上面方法一通过实现 HandlerInterceptor 接口来实现拦截,需要把所有抽象方法都实现,而继承 HandlerInterceptorAdapter 类则可以有选择的重写需要的方法,更加便捷,推荐使用。
① 继承 HandlerInterceptorAdapter 类
1 | public class SecondInterceptor extends HandlerInterceptorAdapter { |
② 配置拦截器
1 | <!-- 配置拦截器 --> |
使用细节
1、拦截地址包含多层路径
1 | <mvc:interceptor> |
2、配置不拦截的地址
在<mvc:mapping>
配置了拦截的地址基础上,使用<mvc:exclude-mapping>
配置不拦截的地址
1 | <mvc:interceptor> |
3、多个拦截器的执行顺序
拦截相同资源的拦截器会构成一个链式结构,它们执行的顺序和配置的顺序有关
- 按正序依次调用 preHandle()方法
- 执行目标 handler 方法
- 按反序调用 postHandle()方法
- 按反序调用 afterCompletion()方法
正序:方法执行的顺序和配置的顺序相同
反序:方法执行的顺序和配置的顺序相反
4、各个方法执行的时机
- preHandle()方法
- 目标 handler 方法
- postHandle()方法
- 渲染视图
- afterCompletion()方法
5、拦截器和过滤器的异同
[1]相同点
三要素一致
[2]不一致
- 工作平台不同
- 拦截器:工作在 SpringMVC 的环境下
- 过滤器:工作在 Servlet 容器中
- 管理的范围不同
- 拦截器:能够拦截的请求,最大范围不会超过 SpringMVC 管理的范围
- 过滤器:能够拦截的请求,最大范围是整个 Web 应用范围
- API 接口不同
- 拦截器:实现
HandlerInterceptor
接口或继承HandlerInterceptorAdapter
类 - 过滤器:实现
javax.servlet.Filter
接口
- 拦截器:实现
- 配置方式不同
- 拦截器:在 SpringMVC 配置文件中配置
- 过滤器:web.xml 中配置
- 应用场景
- 拦截器:在 SpringMVC 环境下,能用拦截器实现的功能都用拦截器,因为它从 IOC 容器中获取 bean 方便
- 过滤器:在没有 SpringMVC 环境或者有 SpringMVC 但拦截器无法实现的情况下,使用过滤器