拦截器和过滤器的区别

拦截器(Interceptor)和过滤器(Filter)都是用于在请求处理过程中进行预处理和后处理的组件,但它们在实现原理、使用场景和功能特点上有显著区别。

拦截器和过滤器的区别

1. 基本概念

过滤器(Filter)

  • 基于函数回调的Java Web组件
  • 实现了Servlet规范,是Servlet技术的一部分
  • 依赖于Servlet容器(如Tomcat)
  • 可以对所有进入容器的请求进行处理

拦截器(Interceptor)

  • 基于Java反射机制的组件
  • 是Spring框架的一部分(Spring MVC中)
  • 不依赖Servlet容器,依赖Spring容器
  • 主要用于拦截Controller层的请求

2. 执行顺序

scss 复制代码
客户端请求
    ↓
Filter1 (前置处理)
    ↓
Filter2 (前置处理)
    ↓
DispatcherServlet
    ↓
Interceptor1 (preHandle)
    ↓
Interceptor2 (preHandle)
    ↓
Controller方法执行
    ↓
Interceptor2 (postHandle)
    ↓
Interceptor1 (postHandle)
    ↓
视图渲染
    ↓
Interceptor2 (afterCompletion)
    ↓
Interceptor1 (afterCompletion)
    ↓
Filter2 (后置处理)
    ↓
Filter1 (后置处理)
    ↓
返回客户端响应

3. 功能对比

特性 过滤器(Filter) 拦截器(Interceptor)
实现原理 基于函数回调 基于Java反射机制
依赖容器 Servlet容器 Spring容器
触发时机 请求进入容器时 请求进入Controller前
拦截范围 所有请求 DispatcherServlet处理的请求
配置方式 web.xml或注解 Spring配置或注解
访问Servlet API 可以直接访问 通过参数访问

4. 代码示例

过滤器示例

java 复制代码
@Component
@WebFilter(urlPatterns = "/*", filterName = "authFilter")
public class AuthFilter implements Filter {
    
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, 
                        FilterChain chain) throws IOException, ServletException {
        
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        
        // 前置处理
        String token = httpRequest.getHeader("Authorization");
        System.out.println("Filter前置处理: " + httpRequest.getRequestURI());
        
        // 继续执行过滤器链
        chain.doFilter(request, response);
        
        // 后置处理
        System.out.println("Filter后置处理: " + httpRequest.getRequestURI());
    }
}

拦截器示例

java 复制代码
@Component
public class AuthInterceptor implements HandlerInterceptor {
    
    @Override
    public boolean preHandle(HttpServletRequest request, 
                           HttpServletResponse response, 
                           Object handler) throws Exception {
        // 请求处理前执行
        System.out.println("Interceptor前置处理: " + request.getRequestURI());
        return true; // 返回true继续执行,false中断执行
    }
    
    @Override
    public void postHandle(HttpServletRequest request, 
                          HttpServletResponse response, 
                          Object handler, 
                          ModelAndView modelAndView) throws Exception {
        // 请求处理后、视图渲染前执行
        System.out.println("Interceptor后置处理: " + request.getRequestURI());
    }
    
    @Override
    public void afterCompletion(HttpServletRequest request, 
                              HttpServletResponse response, 
                              Object handler, 
                              Exception ex) throws Exception {
        // 整个请求完成后执行
        System.out.println("Interceptor完成处理: " + request.getRequestURI());
    }
}

5. 注册方式

过滤器注册

java 复制代码
// 方式1:使用@WebFilter注解
@WebFilter(urlPatterns = "/api/*")
public class MyFilter implements Filter { }

// 方式2:在配置类中注册
@Configuration
public class FilterConfig {
    
    @Bean
    public FilterRegistrationBean<MyFilter> loggingFilter() {
        FilterRegistrationBean<MyFilter> registrationBean = new FilterRegistrationBean<>();
        registrationBean.setFilter(new MyFilter());
        registrationBean.addUrlPatterns("/api/*");
        registrationBean.setOrder(1);
        return registrationBean;
    }
}

拦截器注册

java 复制代码
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    
    @Autowired
    private AuthInterceptor authInterceptor;
    
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(authInterceptor)
                .addPathPatterns("/api/**")
                .excludePathPatterns("/api/login");
    }
}

6. 使用场景

过滤器适用场景

  • 字符编码设置
  • 跨域处理
  • 请求日志记录
  • 权限检查(粗粒度)
  • 请求/响应内容压缩

拦截器适用场景

  • 登录验证
  • 权限检查(细粒度)
  • 性能监控
  • 事务管理
  • 异常处理

7. 性能和开销

  • 过滤器:相对轻量,直接在Servlet容器层面处理,开销较小
  • 拦截器:需要Spring容器管理,会有一些反射调用开销,但功能更强大

两者可以根据具体需求选择使用,也可以结合使用以发挥各自优势。

相关推荐
ZhengEnCi4 小时前
模型训练完整流程:从数据准备到模型上线的 10 个关键步骤(全文可跑)
后端·算法
王中阳Go5 小时前
后端转 Agent 岗面试怎么答:8 个高频问题与应答口径
人工智能·后端·python·大语言模型
程序猿DD5 小时前
OctaFuse Gateway 2.18.0:MCP 接入支持 OAuth,供应商粘性绑定可视化管理
后端
ZhengEnCi6 小时前
Agent 规则管理:让 Memory 做索引、让 Skill 存规则——上下文上限实测与分工方案
后端
nice_lcj5207 小时前
深入理解 Java 反射:从 Class 对象到方法调用(含性能实测 + 迷你 IOC 实战 + 面试考点)
java·开发语言·后端·面试
骑着蜗牛撵大象3277 小时前
2026 后端 AI 工程化:Spring AI 管调用、MCP 管工具、Agent 内嵌管自治
java·人工智能·后端·spring·ai·可观测性·mcp
摸爬滚打的小李8 小时前
Spring XML + WAR + Tomcat 项目启动
后端
IT_陈寒9 小时前
SpringBoot自动配置的坑,这次终于爬出来了
前端·人工智能·后端
RainbowFish9 小时前
# RAG 与智能体记忆:从原理到工程实践 > 一篇给学习者的总结。
后端
苏三说技术10 小时前
为什么越来越多人用Arthas 4 ?
后端