过滤器 Filter vs 拦截器 Interceptor

8539 跨服战场 | 2026-02-26 14:08:34

“Filter 是护城河,Interceptor 是城门守卫。”

如果说 Filter 是应用外围的第一道防线,守护所有进出流量;

那么 Interceptor 就是城内的精锐卫队,只对进入核心区域(Controller)的请求进行精细审查。

两者协同作战,构建了 Web 应用的安全与监控体系。

一、核心概念回顾技术

定义

类比

Filter

Servlet 规范中的组件,在请求到达 Servlet 前拦截,属于容器层

城堡的护城河与外围关卡

Interceptor

Spring MVC 提供的机制,在 Controller 方法执行前后拦截,属于框架层

城内的城门守卫与内务官

二、Filter 深度解析:Servlet 容器的“第一道防线”2.1 Filter 的本质Filter 是 Java Servlet 规范的一部分,由 Servlet 容器(如 Tomcat)管理,不依赖 Spring 框架,因此可以在任何 Java Web 应用中使用。

✅ Filter 的三大生命周期方法:方法

说明

执行时机

init()

初始化

Web 应用启动时调用一次

doFilter()

核心逻辑

每次请求都会调用

destroy()

销毁

Web 应用关闭时调用一次

🔁 执行流程:代码语言:javascript复制Client → Filter1 → Filter2 → ... → Servlet → Controller → View → Filter2 → Filter1 → Client⚠️ 注意:Filter 是双向拦截,既拦截请求,也拦截响应!

2.2 Spring Boot 中使用 Filter✅ 方式一:@WebFilter + @ServletComponentScan代码语言:java复制@WebFilter(urlPatterns = "/api/*", filterName = "encodingFilter")

public class EncodingFilter implements Filter {

@Override

public void doFilter(ServletRequest request, ServletResponse response,

FilterChain chain) throws IOException, ServletException {

// 设置请求编码

request.setCharacterEncoding("UTF-8");

response.setCharacterEncoding("UTF-8");

System.out.println("EncodingFilter: 请求进入");

chain.doFilter(request, response); // 放行

System.out.println("EncodingFilter: 响应返回");

}

}代码语言:java复制@SpringBootApplication

@ServletComponentScan // 扫描 @WebFilter 注解

public class Application {

public static void main(String[] args) {

SpringApplication.run(Application.class, args);

}

}✅ 方式二:通过 @Bean 注册(推荐)代码语言:java复制@Configuration

public class FilterConfig {

@Bean

public FilterRegistrationBean encodingFilter() {

FilterRegistrationBean registrationBean = new FilterRegistrationBean<>();

registrationBean.setFilter(new EncodingFilter());

registrationBean.addUrlPatterns("/api/*");

registrationBean.setOrder(1); // 执行顺序

return registrationBean;

}

}✅ 优势:支持 @Order 控制执行顺序,更灵活。

2.3 Filter 的典型应用场景场景

示例

统一编码设置

解决中文乱码问题

安全过滤

XSS 过滤、SQL 注入防护

日志记录

记录所有请求的 IP、路径、耗时

Gzip 压缩

对响应内容进行压缩

跨域处理

添加 CORS 响应头

身份认证

JWT 校验、Token 解析(在 Spring Security 中常用)

三、Interceptor 深度解析:Spring MVC 的“智能守卫”3.1 Interceptor 的三大拦截时机Interceptor 是 Spring MVC 的组件,只能拦截被 DispatcherServlet 处理的请求(即映射到 Controller 的请求)。

✅ 三个核心方法:方法

执行时机

是否可终止流程

典型用途

preHandle()

Controller 方法执行前

✅ 可返回 false 终止

权限校验、登录验证

postHandle()

Controller 执行后,视图渲染前

❌ 已执行,无法终止

修改 Model、添加公共数据

afterCompletion()

请求处理完成(包括异常)

❌ 无法终止

资源清理、异常日志记录

🔁 执行流程:代码语言:javascript复制DispatcherServlet → preHandle → Controller → postHandle → View Render → afterCompletion → Response3.2 Spring Boot 中使用 Interceptor✅ 创建 Interceptor代码语言:java复制public class LoginInterceptor implements HandlerInterceptor {

@Override

public boolean preHandle(HttpServletRequest request,

HttpServletResponse response,

Object handler) throws Exception {

String uri = request.getRequestURI();

System.out.println("【前置拦截】请求路径: " + uri);

// 模拟登录检查

HttpSession session = request.getSession();

if (session.getAttribute("user") == null && uri.startsWith("/admin")) {

response.sendRedirect("/login");

return false; // 拦截

}

return true; // 放行

}

@Override

public void postHandle(HttpServletRequest request,

HttpServletResponse response,

Object handler,

ModelAndView modelAndView) throws Exception {

if (modelAndView != null) {

modelAndView.addObject("currentTime", new Date());

}

}

@Override

public void afterCompletion(HttpServletRequest request,

HttpServletResponse response,

Object handler,

Exception ex) throws Exception {

if (ex != null) {

System.out.println("【异常】请求发生异常: " + ex.getMessage());

}

}

}✅ 注册 Interceptor代码语言:java复制@Configuration

public class WebConfig implements WebMvcConfigurer {

@Override

public void addInterceptors(InterceptorRegistry registry) {

registry.addInterceptor(new LoginInterceptor())

.addPathPatterns("/admin/**", "/user/**") // 拦截路径

.excludePathPatterns("/login", "/public/**"); // 排除路径

}

}3.3 Interceptor 的典型应用场景场景

示例

权限控制

登录验证、角色权限校验

性能监控

记录 Controller 执行时间

操作日志

记录用户关键操作(如删除、修改)

国际化

根据请求头设置 Locale

接口幂等性

结合 Token 防止重复提交

四、Filter vs Interceptor:全方位对比对比维度

Filter

Interceptor

所属规范

Servlet 规范(J2EE)

Spring MVC 框架

依赖框架

❌ 不依赖 Spring

✅ 必须在 Spring 环境中使用

拦截范围

所有请求(包括静态资源、JSP)

仅 DispatcherServlet 映射的请求(Controller)

执行顺序

在 Servlet 之前执行

在 Controller 之前/之后执行

方法数量

1 个 doFilter()

3 个:preHandle、postHandle、afterCompletion

可获取对象

ServletRequest、ServletResponse

HttpServletRequest、HttpServletResponse、HandlerMethod、ModelAndView

对静态资源拦截

✅ 可以

❌ 默认不拦截(除非 DispatcherServlet 映射 /*)

异常处理

只能捕获 Filter 内部异常

afterCompletion 可捕获 Controller 异常

执行顺序优先级

更早(在 Spring 上下文之前)

稍晚(在 Spring MVC 调度之后)

性能开销

较低(原生 API)

稍高(Spring 反射调用)

五、实战选择指南:什么时候用哪个?✅ 优先使用 Filter 的场景:场景

原因

统一字符编码

需要在请求进入 Servlet 前就设置编码

跨域处理(CORS)

需要处理 OPTIONS 预检请求,早于 Spring MVC

安全过滤(XSS、SQL 注入)

需要对所有输入进行预处理

Gzip 压缩

需要包装 ServletResponse

非 Spring 环境

如纯 Servlet 应用、Filter 链

✅ 优先使用 Interceptor 的场景:场景

原因

登录状态校验

可获取 HttpSession 和 Spring Bean

权限控制

可结合 @PreAuthorize、SecurityContextHolder

性能监控

可精确统计 Controller 执行时间

操作日志记录

可获取 HandlerMethod,知道调用的是哪个方法

模型数据增强

可在 postHandle 中向 ModelAndView 添加数据

六、黄金组合:Filter + Interceptor 协同作战在实际项目中,两者往往配合使用,各司其职:

代码语言:javascript复制Client

[Filter: 统一编码、CORS、安全过滤]

[Filter: Gzip 压缩、日志记录]

DispatcherServlet

[Interceptor: 登录验证]

[Interceptor: 权限校验]

[Interceptor: 性能监控]

Controller

[Interceptor: afterCompletion 记录日志]

[Filter: 响应压缩、日志]

Client✅ 经典组合示例:

Filter:负责 UTF-8 编码、CORS、XSS 过滤Interceptor:负责 登录验证、权限控制、操作日志

七、面试高频题1. Filter 和 Interceptor 的区别?从规范、依赖、拦截范围、执行时机、方法数量等维度回答。

2. Filter 能拦截静态资源吗?Interceptor 呢?Filter 可以;Interceptor 默认不能(除非 DispatcherServlet 映射 /*)。

3. 如何让 Interceptor 拦截所有请求(包括静态资源)?修改 DispatcherServlet 的 url-pattern 为 /*,但需注意性能影响。

4. Filter 的 chain.doFilter() 有什么作用?调用下一个 Filter 或目标资源,是实现链式调用的关键。

5. Interceptor 的 afterCompletion 一定会执行吗?是的,即使 preHandle 返回 false 或发生异常,只要进入了 preHandle,afterCompletion 就会执行。

八、总结:Filter 与 Interceptor 的“黄金搭档”角色

Filter

Interceptor

定位

容器层“守门人”

框架层“执法官”

优势

通用、底层、不依赖框架

精细、灵活、可获取 Spring 上下文

劣势

功能单一、无法获取 Spring Bean

仅限 Spring MVC 请求

最佳实践

处理通用、底层问题

处理业务、安全、监控逻辑

✅ 终极建议:

Filter 做“通用处理”:编码、安全、日志、压缩Interceptor 做“业务拦截”:权限、监控、日志增强二者结合,构建完整拦截体系