HandlerInterceptor 与 Filter

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() 中剩余的代码
    ↓
返回响应给客户端

关键点:

  1. preHandle:如果返回false,则流程中断,后续的Interceptor和Controller都不会执行。
  2. postHandle:在Controller执行后,但视图渲染前执行。此时可以修改ModelAndView。
  3. afterCompletion:在整个请求完成(视图渲染完毕)后执行,用于资源清理。无论请求是否成功,只要preHandle返回true,此方法都会执行。常用于记录异常信息。

使用场景

Filter 的典型使用场景

  1. 字符编码设置:确保所有请求的编码统一为UTF-8。
  2. 跨域资源共享(CORS)处理:在请求头中添加Access-Control-Allow-Origin等字段。
  3. XSS攻击防护:过滤请求参数中的恶意脚本代码。
  4. 全局日志记录:记录所有请求的URL、IP、耗时等基础信息。
  5. GZIP压缩:对响应体进行压缩,减少传输流量。
  6. 与安全相关的粗粒度过滤:例如,根据IP地址黑名单直接拒绝请求。

HandlerInterceptor 的典型使用场景

  1. 用户认证与细粒度授权:检查用户是否登录,以及是否有权限访问特定的API或页面。这是最常用的场景。
  2. 业务逻辑预处理/后处理:
    • 预处理:在Controller执行前,准备一些通用数据(如从Token解析用户信息并放入Request属性)。
    • 后处理:在Controller执行后,对返回的ModelAndView进行修改或添加公共数据。
  3. 性能监控:计算Controller方法的执行时间。
  4. 统一的异常处理(部分):可以捕获preHandle中抛出的异常,但更全局的异常建议使用@ControllerAdvice。
  5. 记录操作日志:记录用户对特定业务数据的操作行为。
本文为原创内容,作者:闲鹤,原文链接:https://blog.uwenya.cc/1661.html,转载请注明出处。

发表评论