过滤器和拦截器的区别
过滤器和拦截器在Web开发中都是用于请求处理的关键组件,但它们在作用范围、实现原理、依赖关系等方面存在显著差异。以下是两者的核心区别及适用场景分析:
一、作用范围与位置
-
过滤器(Filter)
- 作用阶段:在请求进入Servlet容器(如Tomcat)后、Servlet处理之前拦截,并在响应返回客户端之前再次处理。
- 覆盖范围:可处理所有请求类型(包括静态资源如CSS/JS)和响应,甚至可拦截Servlet/JSP页面。
- 典型应用:全局字符编码设置、敏感词过滤、跨域处理。
-
拦截器(Interceptor)
- 作用阶段:仅在Controller层的方法调用前后拦截,属于Spring框架的一部分。
- 覆盖范围:仅针对Action请求(即Controller方法),无法处理静态资源。
- 典型应用:登录状态验证、权限校验、业务日志记录。
二、技术实现与依赖
-
过滤器
- 实现方式:基于Servlet规范,通过实现
javax.servlet.Filter
接口,依赖Servlet容器(如Tomcat)。 - 回调机制:通过函数回调(
doFilter()
方法)处理请求链。 - 代码示例:
public class LoginFilter implements Filter {@Overridepublic void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {// 预处理逻辑chain.doFilter(req, res); // 继续执行后续过滤器或Servlet// 后处理逻辑} }
- 实现方式:基于Servlet规范,通过实现
-
拦截器
- 实现方式:基于Spring框架,通过实现
HandlerInterceptor
接口,依赖Spring容器(可访问Spring Bean)。 - 动态代理:通过反射机制或AOP动态代理实现,支持方法级别的拦截。
- 代码示例:
@Component public class AuthInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object handler) {// 方法执行前的逻辑(如权限校验)return true; // 返回false则中断请求} }
- 实现方式:基于Spring框架,通过实现
三、执行顺序与生命周期
-
执行顺序
- 整体流程:过滤器 → 拦截器 → Controller → 拦截器 → 过滤器。
- 具体阶段:
- 过滤器:在Servlet前后执行(
doFilter()
前后代码块)。 - 拦截器:通过
preHandle()
(Controller前)、postHandle()
(Controller后但未渲染视图)、afterCompletion()
(视图渲染后)三阶段控制。
- 过滤器:在Servlet前后执行(
-
生命周期
- 过滤器:随Servlet容器启动初始化,仅单例模式运行,多次请求共享同一实例。
- 拦截器:由Spring管理,支持多实例,可通过
@Scope
注解配置作用域。
四、功能扩展与局限性
特性 | 过滤器 | 拦截器 |
---|---|---|
依赖容器 | 依赖Servlet容器(如Tomcat) | 依赖Spring框架,不绑定Servlet |
访问Spring资源 | 无法直接注入Spring Bean | 可访问Spring上下文及Bean |
动态参数处理 | 仅支持请求/响应对象 | 可操作ModelAndView 、异常对象 |
适用项目类型 | 仅限Web项目 | 支持Web及非Web项目(如Swing) |
五、适用场景对比
-
选择过滤器的场景:
需处理全局性、与业务无关的功能,如压缩响应数据、统一字符编码、IP黑名单过滤。 -
选择拦截器的场景:
需与业务逻辑深度整合的功能,如动态权限控制(基于用户角色)、请求参数校验、接口性能监控。
总结
过滤器是Servlet层面的“守门人”,负责粗粒度的全局请求处理;而拦截器是Spring框架的“业务助手”,专注于细粒度的Controller逻辑控制。两者可通过组合使用实现多层拦截(如先通过过滤器处理基础安全,再通过拦截器校验业务权限)。