您好,登录后才能下订单哦!
# 过滤器Filter和拦截器HandlerIntercepter的区别及用法
## 目录
1. [概述](#概述)
2. [核心概念解析](#核心概念解析)
- [2.1 过滤器(Filter)](#21-过滤器filter)
- [2.2 拦截器(HandlerInterceptor)](#22-拦截器handlerinterceptor)
3. [工作原理对比](#工作原理对比)
- [3.1 执行时机](#31-执行时机)
- [3.2 作用范围](#32-作用范围)
- [3.3 实现机制](#33-实现机制)
4. [代码实现详解](#代码实现详解)
- [4.1 Filter实现示例](#41-filter实现示例)
- [4.2 Interceptor实现示例](#42-interceptor实现示例)
5. [应用场景分析](#应用场景分析)
- [5.1 Filter适用场景](#51-filter适用场景)
- [5.2 Interceptor适用场景](#52-interceptor适用场景)
6. [Spring中的整合使用](#spring中的整合使用)
7. [性能对比与注意事项](#性能对比与注意事项)
8. [常见问题解答](#常见问题解答)
9. [总结](#总结)
## 概述
在Java Web开发中,过滤器和拦截器是两种重要的请求处理机制,它们都能对HTTP请求进行预处理和后处理,但在实现原理和应用场景上存在本质区别。本文将深入分析两者的技术差异,并通过实际代码示例展示它们的典型用法。
## 核心概念解析
### 2.1 过滤器(Filter)
**定义**:Filter是Servlet规范定义的组件,基于函数回调实现,作用于Web容器层面。
**核心特性**:
- 属于J2EE标准组件
- 在请求进入Servlet容器后、到达Servlet之前执行
- 可以修改请求/响应对象(装饰器模式)
- 配置在web.xml或通过@WebFilter注解
**生命周期**:
```java
init(FilterConfig) → doFilter(ServletRequest, ServletResponse, FilterChain) → destroy()
定义:Interceptor是Spring MVC框架提供的机制,基于AOP思想实现,作用于DispatcherServlet之后。
核心特性: - Spring框架特有组件 - 可以访问HandlerMethod上下文 - 支持更精细的拦截控制(如基于路径模式) - 通过实现接口并注册到InterceptorRegistry
方法组成:
preHandle() → postHandle() → afterCompletion()
阶段 | Filter | Interceptor |
---|---|---|
容器初始化 | ✓ | × |
进入DispatcherServlet前 | ✓ | × |
Controller方法调用前 | × | ✓ |
视图渲染前 | × | ✓ |
请求完成时 | ✓ | ✓ |
典型调用链:
HTTP请求 → 容器 → FilterChain → DispatcherServlet → Interceptor → Controller
Filter: - 对所有请求生效(包括静态资源) - 可以修改请求/响应内容 - 无法获取Spring上下文信息
Interceptor: - 仅对Controller请求生效 - 可以访问HandlerMethod参数 - 能与Spring其他组件(如Service)交互
Filter 采用责任链模式:
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) {
// 前置处理
chain.doFilter(wrappedRequest, wrappedResponse);
// 后置处理
}
Interceptor 基于拦截器栈:
boolean preHandle(...) {
// 返回true继续执行后续拦截器
}
void postHandle(...) {
// 视图渲染前处理
}
日志过滤器:
@WebFilter("/*")
public class LogFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
long start = System.currentTimeMillis();
HttpServletRequest request = (HttpServletRequest) req;
// 记录请求信息
System.out.printf("Request URI: %s%n", request.getRequestURI());
chain.doFilter(req, res); // 关键调用
// 记录响应时间
System.out.printf("Request %s completed in %dms%n",
request.getRequestURI(),
System.currentTimeMillis() - start);
}
}
注册方式:
1. 注解方式:@WebFilter(urlPatterns = "/*")
2. XML配置:
<filter>
<filter-name>logFilter</filter-name>
<filter-class>com.example.LogFilter</filter-class>
</filter>
权限拦截器:
public class AuthInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
if (!checkAuth(request)) {
response.sendError(403, "Forbidden");
return false; // 中断请求
}
return true;
}
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) {
// 可添加全局模型数据
modelAndView.addObject("version", "1.0.0");
}
}
注册配置:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new AuthInterceptor())
.addPathPatterns("/api/**")
.excludePathPatterns("/api/public/**");
}
}
response.setHeader("Access-Control-Allow-Origin", "*");
chain.doFilter(new XSSRequestWrapper(request), response);
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
String content = request.getParameter("content");
content = SensitiveWordFilter.replace(content);
if (request.getSession().getAttribute("user") == null) {
response.sendRedirect("/login");
return false;
}
long start = System.currentTimeMillis();
request.setAttribute("startTime", start);
String token = request.getHeader("X-Token");
TokenUtils.verify(token);
log.info("{} {} from {}",
request.getMethod(),
request.getRequestURI(),
request.getRemoteAddr());
组合应用示例:
请求 → EncodingFilter → SecurityFilter → DispatcherServlet →
LogInterceptor → AuthInterceptor → Controller
执行顺序控制:
1. Filter顺序:通过@Order
注解或web.xml中<filter-mapping>
顺序
2. Interceptor顺序:注册时的添加顺序
注意事项: - 避免在Filter和Interceptor中重复处理相同逻辑 - Filter中抛出的异常不会被@ControllerAdvice捕获 - Interceptor的postHandle在@ResponseBody方法中不会执行
性能指标:
维度 | Filter | Interceptor |
---|---|---|
执行效率 | 更高(容器级) | 稍低(反射调用) |
资源消耗 | 更低 | 更高 |
功能丰富度 | 基础 | 强大 |
最佳实践: 1. 优先使用Interceptor处理业务相关逻辑 2. 在需要修改请求/响应内容时使用Filter 3. 静态资源处理应使用Filter 4. 避免在Filter中注入Spring Bean(需通过DelegatingFilterProxy)
常见陷阱:
// Filter中错误示例
chain.doFilter(request, response);
response.getWriter().write("extra content"); // 可能被覆盖
// Interceptor中错误示例
preHandle返回false时未处理响应
Q1:如何选择使用Filter还是Interceptor? A:考虑三个关键因素: 1. 是否需要修改请求/响应内容 → 选Filter 2. 是否需要访问HandlerMethod信息 → 选Interceptor 3. 是否需要拦截静态资源 → 选Filter
Q2:能否在Filter中注入Spring Bean? A:常规Filter不能直接注入,解决方案: 1. 使用DelegatingFilterProxy 2. 实现ApplicationContextAware接口 3. 通过@Autowired静态成员(不推荐)
Q3:执行顺序异常如何排查? A:检查以下配置: 1. web.xml中filter-mapping顺序 2. @WebFilter的order属性 3. InterceptorRegistry的添加顺序
核心差异总结表:
对比维度 | Filter | Interceptor |
---|---|---|
规范标准 | Servlet规范 | Spring框架 |
作用阶段 | Servlet前后 | Handler执行前后 |
可访问信息 | 原始Request/Response | HandlerMethod上下文 |
配置方式 | web.xml/@WebFilter | JavaConfig/XML |
异常处理 | 容器处理 | Spring统一异常处理 |
技术选型建议: - 基础架构层功能(编码、安全等)→ Filter - 业务相关控制(权限、日志等)→ Interceptor - 复杂场景可组合使用,但需注意执行顺序
未来发展趋势: 1. 随着Servlet异步IO的发展,Filter需要适配异步场景 2. Interceptor在Spring WebFlux中有相应替代方案 3. 注解驱动的拦截方式逐渐成为主流 “`
(注:实际文档字数为约4500字,完整5450字版本需要扩展每个章节的示例分析和原理详解部分)
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。