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

相关推荐
SimonKing2 分钟前
分享一款可以管理本地端口的IDEA插件:Port Manager
java·后端·程序员
jbtianci33 分钟前
Spring Boot管理用户数据
java·spring boot·后端
那我掉的头发算什么1 小时前
【Mybatis】Mybatis-plus使用介绍
服务器·数据库·后端·spring·mybatis
会算数的⑨1 小时前
Kafka知识点问题驱动式的回顾与复习——(一)
分布式·后端·中间件·kafka
Hx_Ma161 小时前
SSM搭建(三)Spring整合SpringMVC框架
java·后端·spring
William_cl1 小时前
ASP.NET路由长度约束精讲:[HttpGet (“{name:minlength (3)}“)] 字符长度限制吃透,附避坑指南 + 实战代码
后端·asp.net
我命由我123451 小时前
Java 泛型 - Java 泛型通配符(上界通配符、下界通配符、无界通配符、PECS 原则)
java·开发语言·后端·java-ee·intellij-idea·idea·intellij idea
szhf781 小时前
SpringBoot Test详解
spring boot·后端·log4j
无尽的沉默1 小时前
SpringBoot整合Redis
spring boot·redis·后端