Spring中过滤器和拦截器的区别及具体实现

在 Spring 框架中,过滤器(Filter)拦截器(Interceptor) 都是用于处理 HTTP 请求的中间件,但它们在作用范围、实现方式和生命周期上有显著区别。以下是详细对比和实现方式:


核心区别

特性 过滤器 (Filter) 拦截器 (Interceptor)
规范 Servlet 规范 (J2EE 标准) Spring 框架特有
作用范围 所有 Web 资源(Servlet、JSP、静态资源) 仅 Spring MVC 管理的 Controller 请求
依赖 依赖 Servlet 容器(如 Tomcat) 依赖 Spring 容器
拦截时机 在请求进入 Servlet 前 / 响应发送到客户端前 在请求进入 Controller 前 / 后 / 视图渲染后
获取 Spring Bean 不能直接获取(需通过工具类) 可直接获取 Spring Bean
异常处理 无法使用 Spring 的异常处理机制 可结合 @ControllerAdvice 统一异常处理

实现方式

1. 过滤器 (Filter) 实现

过滤器是 Servlet 规范的一部分,通过实现 javax.servlet.Filter 接口实现。

步骤:

  1. 创建 Filter 类
java 复制代码
import javax.servlet.*;
import java.io.IOException;

public class CustomFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) {
        // 初始化逻辑
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
        throws IOException, ServletException {
        // 1. 请求到达 Controller 前的逻辑
        System.out.println("Before Controller (Filter)");
        
        // 放行请求
        chain.doFilter(request, response);
        
        // 2. 响应返回客户端前的逻辑
        System.out.println("After Controller (Filter)");
    }

    @Override
    public void destroy() {
        // 销毁逻辑
    }
}
  1. 注册过滤器(Spring Boot 中)
java 复制代码
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FilterConfig {
    @Bean
    public FilterRegistrationBean<CustomFilter> customFilter() {
        FilterRegistrationBean<CustomFilter> bean = new FilterRegistrationBean<>();
        bean.setFilter(new CustomFilter());
        bean.addUrlPatterns("/*"); // 拦截所有路径
        bean.setOrder(1); // 执行顺序
        return bean;
    }
}

2. 拦截器 (Interceptor) 实现

拦截器是 Spring MVC 的组件,通过实现 HandlerInterceptor 接口。

步骤:

  1. 创建 Interceptor 类
java 复制代码
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

@Component
public class CustomInterceptor implements HandlerInterceptor {
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        // 在 Controller 方法执行前调用
        System.out.println("Before Controller (Interceptor)");
        return true; // true=放行, false=中断请求
    }
    
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, 
                           ModelAndView modelAndView) {
        // 在 Controller 方法执行后、视图渲染前调用
        System.out.println("After Controller (Interceptor)");
    }
    
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, 
                                Object handler, Exception ex) {
        // 在整个请求完成后调用(视图渲染完毕)
        System.out.println("After View Render (Interceptor)");
    }
}
  1. 注册拦截器
java 复制代码
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    
    @Autowired
    private CustomInterceptor customInterceptor;
    
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(customInterceptor)
                .addPathPatterns("/**")    // 拦截所有路径
                .excludePathPatterns("/login"); // 排除路径
    }
}

执行顺序示例

假设请求路径被过滤器和拦截器同时拦截:

复制代码
1. Filter: doFilter() [前逻辑]
2. Interceptor: preHandle()
3. Controller 方法执行
4. Interceptor: postHandle()
5. 视图渲染
6. Interceptor: afterCompletion()
7. Filter: doFilter() [后逻辑]

如何选择?

场景 推荐使用
全局日志、字符编码、安全过滤 Filter
权限验证、参数预处理 Interceptor
需要 Spring 容器功能 Interceptor
非 Spring 项目 Filter

最佳实践:优先使用 Interceptor(可集成 Spring 特性),若需处理静态资源或深度请求/响应修改,则用 Filter。

相关推荐
:Concerto19 分钟前
JavaSE 注解
java·开发语言·sprint
电商API_180079052471 小时前
第三方淘宝商品详情 API 全维度调用指南:从技术对接到生产落地
java·大数据·前端·数据库·人工智能·网络爬虫
一点程序1 小时前
基于SpringBoot的选课调查系统
java·spring boot·后端·选课调查系统
C雨后彩虹1 小时前
计算疫情扩散时间
java·数据结构·算法·华为·面试
2601_949809591 小时前
flutter_for_openharmony家庭相册app实战+我的Tab实现
java·javascript·flutter
vx_BS813302 小时前
【直接可用源码免费送】计算机毕业设计精选项目03574基于Python的网上商城管理系统设计与实现:Java/PHP/Python/C#小程序、单片机、成品+文档源码支持定制
java·python·课程设计
2601_949868362 小时前
Flutter for OpenHarmony 电子合同签署App实战 - 已签合同实现
java·开发语言·flutter
达文汐2 小时前
【困难】力扣算法题解析LeetCode332:重新安排行程
java·数据结构·经验分享·算法·leetcode·力扣
培风图南以星河揽胜2 小时前
Java版LeetCode热题100之零钱兑换:动态规划经典问题深度解析
java·leetcode·动态规划
启山智软3 小时前
【中大企业选择源码部署商城系统】
java·spring·商城开发