过滤器(Filter)与拦截器(Interceptor)的原理与实现
字数 1275 2025-11-05 23:47:39

过滤器(Filter)与拦截器(Interceptor)的原理与实现

描述
过滤器和拦截器是Web框架中用于处理HTTP请求的两种重要组件,它们可以在请求到达目标处理器(如Controller方法)之前或之后执行特定逻辑。虽然功能相似,但它们在实现原理、作用范围和使用场景上存在关键差异。理解它们的区别和适用场景是后端开发的重要知识点。

解题过程

  1. 基本概念与定位

    • 过滤器(Filter):基于Servlet规范,是Java Web应用的标准组件。它在Servlet容器级别工作,可以对所有进入容器的请求进行预处理,也能对响应进行后处理。过滤器像是"管道",请求和响应必须通过它。
    • 拦截器(Interceptor):是Spring MVC等框架层面的组件。它在DispatcherServlet将请求分发给具体Controller前后工作,更贴近业务逻辑。拦截器像是"关卡",只在框架内部的关键节点起作用。
  2. 实现原理深度解析

    过滤器实现机制:

    • 过滤器通过实现javax.servlet.Filter接口,重写三个核心方法:
      public class LogFilter implements Filter {
          @Override
          public void init(FilterConfig filterConfig) throws ServletException {
              // 初始化逻辑
          }
      
          @Override
          public void doFilter(ServletRequest request, ServletResponse response, 
                             FilterChain chain) throws IOException, ServletException {
              // 1. 请求到达目标前的预处理(如日志记录、权限检查)
              long startTime = System.currentTimeMillis();
      
              // 2. 调用chain.doFilter()将控制权交给下一个过滤器或目标Servlet
              chain.doFilter(request, response);
      
              // 3. 目标处理完成后的后处理(如记录耗时、修改响应头)
              long cost = System.currentTimeMillis() - startTime;
              System.out.println("请求处理耗时:" + cost + "ms");
          }
      
          @Override
          public void destroy() {
              // 资源清理逻辑
          }
      }
      
    • 过滤器链(FilterChain)维护过滤器的执行顺序,通过责任链模式实现

    拦截器实现机制:

    • 拦截器通过实现HandlerInterceptor接口,重写三个关键方法:
      public class AuthInterceptor implements HandlerInterceptor {
          @Override
          public boolean preHandle(HttpServletRequest request, 
                                 HttpServletResponse response, Object handler) {
              // 在Controller方法执行前调用
              // 返回true则继续执行,false则中断流程
              if (!checkAuth(request)) {
                  response.sendError(403, "无访问权限");
                  return false;
              }
              return true;
          }
      
          @Override
          public void postHandle(HttpServletRequest request, 
                               HttpServletResponse response, Object handler,
                               ModelAndView modelAndView) {
              // Controller方法执行后,视图渲染前调用
              // 可修改ModelAndView
          }
      
          @Override
          public void afterCompletion(HttpServletRequest request,
                                    HttpServletResponse response, 
                                    Object handler, Exception ex) {
              // 整个请求完成后调用(视图已渲染)
              // 适合资源清理、异常记录
          }
      }
      
  3. 执行顺序与作用范围对比

    • 完整执行流程(以Spring MVC为例):

      1. HTTP请求 → Servlet容器
      2. 经过所有配置的过滤器(按web.xml中配置的顺序)
      3. 到达DispatcherServlet(Spring MVC前端控制器)
      4. 执行拦截器的preHandle方法(按注册顺序)
      5. 执行目标Controller方法
      6. 执行拦截器的postHandle方法(按注册逆序)
      7. 视图渲染
      8. 执行拦截器的afterCompletion方法(按注册逆序)
      9. 响应经过过滤器的后处理(按web.xml中配置的逆序)
    • 作用范围差异

      • 过滤器:可过滤所有请求(静态资源、JSP、Controller等)
      • 拦截器:只对Spring管理的Controller请求有效
  4. 典型应用场景

    • 适合使用过滤器的场景

      • 请求/响应编码设置(CharacterEncodingFilter)
      • 跨域请求处理(CORS Filter)
      • 敏感词过滤、XSS防护
      • GZIP压缩响应
    • 适合使用拦截器的场景

      • 用户身份认证与授权检查
      • 请求日志记录(需要业务参数时)
      • 接口执行时间统计
      • 统一异常处理和数据封装
  5. 高级特性与最佳实践

    • 过滤器注册方式

      • 传统web.xml配置
      • Spring Boot中使用@Component + @Order
    • 拦截器配置示例

      @Configuration
      public class WebConfig implements WebMvcConfigurer {
          @Override
          public void addInterceptors(InterceptorRegistry registry) {
              registry.addInterceptor(new AuthInterceptor())
                     .addPathPatterns("/api/**")  // 拦截路径
                     .excludePathPatterns("/api/public/**"); // 排除路径
          }
      }
      

关键总结

  • 过滤器工作在更底层(Servlet容器层面),拦截器工作在框架层面
  • 过滤器可获取原始ServletRequest/Response,拦截器获取的是框架封装后的对象
  • 拦截器能直接获取处理请求的Controller方法信息,更适合业务相关处理
  • 实际项目中常组合使用:过滤器处理通用技术问题,拦截器处理业务横切关注点
过滤器(Filter)与拦截器(Interceptor)的原理与实现 描述 过滤器和拦截器是Web框架中用于处理HTTP请求的两种重要组件,它们可以在请求到达目标处理器(如Controller方法)之前或之后执行特定逻辑。虽然功能相似,但它们在实现原理、作用范围和使用场景上存在关键差异。理解它们的区别和适用场景是后端开发的重要知识点。 解题过程 基本概念与定位 过滤器(Filter) :基于Servlet规范,是Java Web应用的标准组件。它在Servlet容器级别工作,可以对所有进入容器的请求进行预处理,也能对响应进行后处理。过滤器像是"管道",请求和响应必须通过它。 拦截器(Interceptor) :是Spring MVC等框架层面的组件。它在DispatcherServlet将请求分发给具体Controller前后工作,更贴近业务逻辑。拦截器像是"关卡",只在框架内部的关键节点起作用。 实现原理深度解析 过滤器实现机制: 过滤器通过实现 javax.servlet.Filter 接口,重写三个核心方法: 过滤器链(FilterChain)维护过滤器的执行顺序,通过责任链模式实现 拦截器实现机制: 拦截器通过实现 HandlerInterceptor 接口,重写三个关键方法: 执行顺序与作用范围对比 完整执行流程 (以Spring MVC为例): HTTP请求 → Servlet容器 经过所有配置的过滤器(按web.xml中配置的顺序) 到达DispatcherServlet(Spring MVC前端控制器) 执行拦截器的preHandle方法(按注册顺序) 执行目标Controller方法 执行拦截器的postHandle方法(按注册逆序) 视图渲染 执行拦截器的afterCompletion方法(按注册逆序) 响应经过过滤器的后处理(按web.xml中配置的逆序) 作用范围差异 : 过滤器:可过滤所有请求(静态资源、JSP、Controller等) 拦截器:只对Spring管理的Controller请求有效 典型应用场景 适合使用过滤器的场景 : 请求/响应编码设置(CharacterEncodingFilter) 跨域请求处理(CORS Filter) 敏感词过滤、XSS防护 GZIP压缩响应 适合使用拦截器的场景 : 用户身份认证与授权检查 请求日志记录(需要业务参数时) 接口执行时间统计 统一异常处理和数据封装 高级特性与最佳实践 过滤器注册方式 : 传统web.xml配置 Spring Boot中使用 @Component + @Order 拦截器配置示例 : 关键总结 过滤器工作在更底层(Servlet容器层面),拦截器工作在框架层面 过滤器可获取原始ServletRequest/Response,拦截器获取的是框架封装后的对象 拦截器能直接获取处理请求的Controller方法信息,更适合业务相关处理 实际项目中常组合使用:过滤器处理通用技术问题,拦截器处理业务横切关注点