HandlerInterceptor 和 Filter 都是用于在请求处理过程中进行拦截和处理的机制,但它们在Spring MVC框架中的层级、功能和使用场景上有显著区别
- Filter(过滤器):是Servlet规范的一部分,属于Web容器级别的拦截器。它可以拦截所有进入Servlet容器的请求(包括静态资源如JSP、HTML、CSS、JS等),在任何框架(如Spring MVC、Struts)处理请求之前和之后执行。
- HandlerInterceptor(处理器拦截器):是Spring MVC框架的一部分,属于Spring框架级别的拦截器。它只能拦截进入Spring MVC控制器的请求(即被@Controller注解的类或Controller接口的实现类处理的请求),无法拦截直接访问的静态资源。它在DispatcherServlet内部,在调用具体处理器(Controller)前后以及视图渲染后执行。
详细对比
| 特性 | Filter (过滤器) | HandlerInterceptor (处理器拦截器) |
|---|---|---|
| 规范/所属 | Servlet规范,任何Java Web项目都可使用 | Spring Framework,仅Spring MVC项目可用 |
| 拦截范围 | 所有请求,包括静态资源、JSP、Servlet、Controller等 | 仅Spring MVC控制器的请求,不拦截静态资源 |
| 执行顺序 | 在Servlet之前执行 | 在DispatcherServlet之后,Controller之前执行 |
| 依赖注入 | 默认不支持,需通过DelegatingFilterProxy与Spring容器集成 | 天然支持,可以注入Spring容器中的任何Bean |
| 实现方式 | 实现 javax.servlet.Filter 接口 | 实现 org.springframework.web.servlet.HandlerInterceptor 接口 |
| 控制粒度 | 较粗,基于URL模式匹配 | 较细,可获取Handler、ModelAndView等信息,可进行更精细的控制 |
| 典型用途 | 编码设置、CORS、XSS防护、日志记录、权限验证(粗粒度)、GZIP压缩 | 登录验证、权限检查(细粒度)、日志记录(记录Controller方法耗时)、性能监控、预处理/后处理模型数据 |
执行流程与生命周期
一个完整的HTTP请求在Spring MVC + Servlet环境下的执行顺序如下:
客户端请求
↓
Servlet容器 (Tomcat/Jetty)
↓
执行所有匹配的 Filter.doFilter()
↓
进入 Spring MVC 的 DispatcherServlet
↓
执行所有匹配的 HandlerInterceptor.preHandle() 【顺序执行】
↓
执行目标 Controller 的方法
↓
执行所有匹配的 HandlerInterceptor.postHandle() 【逆序执行】
↓
渲染视图 (View)
↓
执行所有匹配的 HandlerInterceptor.afterCompletion() 【逆序执行】
↓
继续执行 Filter.doFilter() 中剩余的代码
↓
返回响应给客户端
关键点:
- preHandle:如果返回false,则流程中断,后续的Interceptor和Controller都不会执行。
- postHandle:在Controller执行后,但视图渲染前执行。此时可以修改ModelAndView。
- afterCompletion:在整个请求完成(视图渲染完毕)后执行,用于资源清理。无论请求是否成功,只要preHandle返回true,此方法都会执行。常用于记录异常信息。
使用场景
Filter 的典型使用场景
- 字符编码设置:确保所有请求的编码统一为UTF-8。
- 跨域资源共享(CORS)处理:在请求头中添加Access-Control-Allow-Origin等字段。
- XSS攻击防护:过滤请求参数中的恶意脚本代码。
- 全局日志记录:记录所有请求的URL、IP、耗时等基础信息。
- GZIP压缩:对响应体进行压缩,减少传输流量。
- 与安全相关的粗粒度过滤:例如,根据IP地址黑名单直接拒绝请求。
HandlerInterceptor 的典型使用场景
- 用户认证与细粒度授权:检查用户是否登录,以及是否有权限访问特定的API或页面。这是最常用的场景。
- 业务逻辑预处理/后处理:
- 预处理:在Controller执行前,准备一些通用数据(如从Token解析用户信息并放入Request属性)。
- 后处理:在Controller执行后,对返回的ModelAndView进行修改或添加公共数据。
- 性能监控:计算Controller方法的执行时间。
- 统一的异常处理(部分):可以捕获preHandle中抛出的异常,但更全局的异常建议使用@ControllerAdvice。
- 记录操作日志:记录用户对特定业务数据的操作行为。
本文为原创内容,作者:闲鹤,原文链接:https://blog.uwenya.cc/1661.html,转载请注明出处。