spring 中 OncePerRequestFilter 的作用以及使用场景,每个请求只触发一次
·
OncePerRequestFilter 的作用与使用场景
作用
OncePerRequestFilter 是 Spring 提供的一个抽象基类,它继承自 GenericFilterBean 并实现了 Filter 接口。它的主要目的是确保在一次请求中过滤器逻辑只执行一次。
当一个 HTTP 请求进入应用时,可能会被多个 Filter 处理。而某些情况下(例如异步请求或转发请求),同一个 Filter 可能会被调用多次。为了避免重复处理带来的副作用,Spring 提供了 OncePerRequestFilter 来保证每个请求只会触发该过滤器一次。
使用场景
-
跨域配置
- 避免在请求链路中有多个相同 CORS 设置操作。
-
权限验证 / 认证
- 在请求到达业务逻辑前检查用户身份认证状态。
- 确保不会因为多次拦截导致重复校验 token 或 session。
-
日志记录
- 统计请求耗时、记录访问日志等。
- 保证每条请求只统计一次,避免数据混乱。
-
请求包装
- 对原始
HttpServletRequest进行增强或替换。 - 比如解密 body 内容、统一参数预处理等。
- 对原始
常见使用案例
@Component
@WebFilter(filterName = "loggingFilter", urlPatterns = "/*")
public class LoggingFilter extends OncePerRequestFilter {
private static final Logger logger = LoggerFactory.getLogger(LoggingFilter.class);
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
long startTime = System.currentTimeMillis();
String uri = request.getRequestURI();
logger.info("Request started: {} {}", request.getMethod(), uri);
try {
// 继续执行后续过滤器和目标资源
filterChain.doFilter(request, response);
} finally {
long duration = System.currentTimeMillis() - startTime;
logger.info("Request finished: {} {} took {} ms", request.getMethod(), uri, duration);
}
}
}
在这个例子中:
- 日志只会在请求开始和结束各打印一次。
- 即使有其他
Filter调用了多次当前LoggingFilter实例的方法,由于其继承了OncePerRequestFilter,实际的方法也只会被执行一次。 - 从而有效防止日志重复输出的问题。
总结来说,如果你希望某个 Filter 的核心逻辑对每一个 HTTP 请求仅运行一次,则推荐继承 OncePerRequestFilter 并重写 doFilterInternal() 方法来实现具体功能。
以上内容由AI大模型生成,注意识别!
更多推荐


所有评论(0)