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,这样可以避免潜在的重复处理问题,提升应用的稳定性。

相关推荐
Home39 分钟前
23种设计模式之代理模式(结构型模式二)
java·后端
程序员西西41 分钟前
详细介绍Spring Boot中用到的JSON序列化技术?
java·后端
课程xingkeit与top41 分钟前
大数据硬核技能进阶:Spark3实战智能物业运营系统(完结)
后端
课程xingkeit与top41 分钟前
基于C++从0到1手写Linux高性能网络编程框架(超清)
后端
语落心生41 分钟前
探秘新一代向量存储格式Lance-format (二十二) 表达式与投影
后端
码事漫谈1 小时前
音域之舞-基于Rokid CXR-M SDK的AI眼镜沉浸式K歌评分系统开发全解析
后端
上进小菜猪1 小时前
基于 Rokid CXR-S SDK 的智能提词器开发全解析——AI 应答辅助系统
后端
Rust语言中文社区1 小时前
【Rust日报】 丰田“先锋”选择了 Rust
开发语言·后端·rust
椎4951 小时前
苍穹外卖资源点整理+个人错误解析-Day10-订单状态定时处理(Spring Task)、来单提醒和客户催单
java·后端·spring