OncePerRequestFilter

OncePerRequestFilter是Spring框架提供的一个过滤器基类,它的核心作用是‌确保在一次完整的HTTP请求中,过滤器的逻辑只会被执行一次‌,即使请求在服务器内部经过了多次转发或包含多个资源请求‌23。

🔍 核心原理

OncePerRequestFilter通过内部机制跟踪当前请求是否已经被处理过:

  • 使用HttpServletRequest的getAttribute和setAttribute方法
  • 结合ThreadLocal变量来标记请求状态
  • 首次请求时执行过滤器逻辑并设置标记,后续直接跳过‌3

⚡ 与普通Filter的区别

特性 Filter OncePerRequestFilter
执行次数 可能多次执行 保证仅执行一次
来源 Servlet容器规范 Spring框架提供
适用场景 基础过滤需求 需要精确控制过滤次数的场景‌4

💡 为什么需要OncePerRequestFilter?

主要有两个原因:

  1. 适配不同Web容器‌:并非所有容器都保证过滤器只执行一次‌2
  2. 兼容异步请求‌:Servlet 3.0+中,异步分发可能导致过滤器重复执行‌2

🛠️ 使用示例

java 复制代码
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class TimingFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request, 
                                   HttpServletResponse response, 
                                   FilterChain filterChain) 
            throws ServletException, IOException {
        
        // 记录请求开始时间
        long startTime = System.currentTimeMillis();
        
        // 继续过滤器链
        filterChain.doFilter(request, response);
        
        // 记录请求处理时间
        long endTime = System.currentTimeMillis();
        long duration = endTime - startTime;
        
        System.out.println("Request took " + duration + " ms to process");
    }
}

📚 实践建议

在Spring环境下开发过滤器时,推荐继承OncePerRequestFilter而不是直接实现Filter接口‌‌2。这样可以避免因容器差异导致的重复执行问题,确保过滤器逻辑的可靠性。

建议‌:在你的下一个Spring项目中,将自定义过滤器改为继承OncePerRequestFilter,这样可以避免潜在的重复处理问题,提升应用的稳定性。

相关推荐
问今域中12 分钟前
Spring Boot 请求参数绑定注解
java·spring boot·后端
计算机程序设计小李同学19 分钟前
婚纱摄影集成管理系统小程序
java·vue.js·spring boot·后端·微信小程序·小程序
一 乐1 小时前
绿色农产品销售|基于springboot + vue绿色农产品销售系统(源码+数据库+文档)
java·前端·数据库·vue.js·spring boot·后端·宠物
3***68841 小时前
Spring Boot中使用Server-Sent Events (SSE) 实现实时数据推送教程
java·spring boot·后端
C***u1761 小时前
Spring Boot问题总结
java·spring boot·后端
上进小菜猪1 小时前
基于 YOLOv8 的人体与行人检测智能识别实战 [目标检测完整源码]
后端
Elieal1 小时前
5 种方式快速创建 SpringBoot 项目
java·spring boot·后端
c***69302 小时前
Spring Boot实时推送技术详解:三个经典案例
spring boot·后端·状态模式
Mr -老鬼2 小时前
Rust适合干什么?为什么需要Rust?
开发语言·后端·rust
12344522 小时前
Agent入门实战-一个题目生成Agent
人工智能·后端