拦截器 vs 过滤器

拦截器(Interceptor)vs 过滤器(Filter)对比笔记

拦截器和过滤器均用于请求处理的 “增强”,但二者在技术归属、作用范围、执行时机等核心维度差异显著,以下从多维度对比梳理:

一、核心差异对比表

对比维度 拦截器(Interceptor) 过滤器(Filter)
技术归属 SpringMVC 框架组件 Java Servlet 规范组件
作用范围 仅作用于 SpringMVC 管理的请求(如 @Controller 接口) 作用于所有 Servlet 容器接收的请求(包括静态资源、JSP 等)
执行时机 在 DispatcherServlet 之后、目标方法前后执行 在 DispatcherServlet 之前 执行(请求进入 Servlet 容器的第一道拦截)
拦截内容 可拦截请求、目标方法、响应数据(能获取 HandlerMethodModelAndView 等 Spring 对象) 仅能拦截请求和响应的 “字节流”(无法直接获取 Spring 相关对象)
配置方式 需实现 WebMvcConfigurer 接口,通过 InterceptorRegistry 配置 1. 实现 Filter 接口;2. 用 @WebFilter 注解或在配置类中注册 FilterRegistrationBean
依赖环境 依赖 Spring 容器(需 Spring 环境支持) 不依赖 Spring,仅需 Servlet 容器(如 Tomcat)
执行顺序控制 多个拦截器按 addInterceptor 注册顺序,preHandle 正序、postHandle 倒序 多个过滤器按 FilterRegistrationBean 的 setOrder 方法指定的数字排序(数字越小越先执行)

二、核心功能与适用场景

1. 拦截器(Interceptor):Spring 生态内的 “精准增强”

适用于需要结合 Spring 组件的场景,能深度介入 SpringMVC 的请求处理流程。

  • 典型场景
    • 权限验证:获取 HandlerMethod 中的注解(如 @RequiresLogin),判断用户是否登录。
    • 日志记录:记录目标方法的参数、返回值(需通过 HandlerMethod 反射获取)。
    • 数据共享:在 postHandle 中修改 ModelAndView,补充页面渲染所需的公共数据。

2. 过滤器(Filter):Servlet 容器级的 “全局拦截”

适用于需要对所有请求(包括非 Spring 管理的资源)进行统一处理的场景。

  • 典型场景
    • 编码统一:设置请求 / 响应的字符编码(如 UTF-8),避免乱码。
    • 跨域处理:在响应头中添加 Access-Control-Allow-Origin 等跨域字段(Servlet 层面的跨域配置)。
    • 全局日志:记录所有请求的 URL、IP、请求方式(包括静态资源请求,如 CSS、JS)。
    • 敏感字符过滤:对请求参数中的敏感词(如 “脏话”)进行替换或拦截。

三、执行顺序链路(请求处理全流程)

当一个请求同时经过过滤器和拦截器时,完整执行顺序如下:

1
2
3
4
1. 客户端发起请求 → 2. 过滤器1执行 → 3. 过滤器2执行 → ... → 4. DispatcherServlet 接收请求 → 
2. 拦截器1.preHandle → 6. 拦截器2.preHandle → ... → 7. 目标方法(@Controller 接口)执行 →
3. 拦截器2.postHandle → 9. 拦截器1.postHandle → 10. 页面渲染 →
4. 拦截器2.afterCompletion → 12. 拦截器1.afterCompletion → 13. 过滤器2执行(后置) → 14. 过滤器1执行(后置) → 15. 响应返回客户端

四、关键使用建议

  1. 优先选过滤器的场景:需处理非 Spring 管理的资源(如静态资源)、需在 Servlet 最早期拦截请求(如编码设置)。
  2. 优先选拦截器的场景:需结合 Spring 组件(如 @ControllerModelAndView)、需精细控制目标方法前后的逻辑(如权限注解判断)。
  3. 协同使用场景:过滤器做 “全局基础处理”(如编码、跨域),拦截器做 “Spring 内精准增强”(如接口权限、方法日志),二者配合实现完整的请求增强链路。