温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

过滤器Filter和拦截器HandlerIntercepter的区别及用法

发布时间:2021-06-23 09:30:06 来源:亿速云 阅读:666 作者:chen 栏目:大数据
# 过滤器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() 

2.2 拦截器(HandlerInterceptor)

定义:Interceptor是Spring MVC框架提供的机制,基于AOP思想实现,作用于DispatcherServlet之后。

核心特性: - Spring框架特有组件 - 可以访问HandlerMethod上下文 - 支持更精细的拦截控制(如基于路径模式) - 通过实现接口并注册到InterceptorRegistry

方法组成

preHandle() → postHandle() → afterCompletion() 

工作原理对比

3.1 执行时机

阶段 Filter Interceptor
容器初始化 ×
进入DispatcherServlet前 ×
Controller方法调用前 ×
视图渲染前 ×
请求完成时

典型调用链:

HTTP请求 → 容器 → FilterChain → DispatcherServlet → Interceptor → Controller 

3.2 作用范围

Filter: - 对所有请求生效(包括静态资源) - 可以修改请求/响应内容 - 无法获取Spring上下文信息

Interceptor: - 仅对Controller请求生效 - 可以访问HandlerMethod参数 - 能与Spring其他组件(如Service)交互

3.3 实现机制

Filter 采用责任链模式:

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) { // 前置处理 chain.doFilter(wrappedRequest, wrappedResponse); // 后置处理 } 

Interceptor 基于拦截器栈:

boolean preHandle(...) { // 返回true继续执行后续拦截器 } void postHandle(...) { // 视图渲染前处理 } 

代码实现详解

4.1 Filter实现示例

日志过滤器

@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> 

4.2 Interceptor实现示例

权限拦截器

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/**"); } } 

应用场景分析

5.1 Filter适用场景

  1. 跨域处理
response.setHeader("Access-Control-Allow-Origin", "*"); 
  1. 请求/响应包装
chain.doFilter(new XSSRequestWrapper(request), response); 
  1. 全局编码设置
request.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8"); 
  1. 敏感词过滤
String content = request.getParameter("content"); content = SensitiveWordFilter.replace(content); 

5.2 Interceptor适用场景

  1. 权限验证
if (request.getSession().getAttribute("user") == null) { response.sendRedirect("/login"); return false; } 
  1. 接口耗时统计
long start = System.currentTimeMillis(); request.setAttribute("startTime", start); 
  1. 参数预处理
String token = request.getHeader("X-Token"); TokenUtils.verify(token); 
  1. 日志记录
log.info("{} {} from {}", request.getMethod(), request.getRequestURI(), request.getRemoteAddr()); 

Spring中的整合使用

组合应用示例

请求 → 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字版本需要扩展每个章节的示例分析和原理详解部分)

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI