doFilter和doFilterInternal
摘录自:https://www.jianshu.com/p/3d9b4cfe1a62
doFilter是整个过滤器最底层的概念Filter接口中的方法
所有过滤器都要实现Filter
package javax.servlet; import java.io.IOException; public interface Filter { void init(FilterConfig var1) throws ServletException; void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException; void destroy(); }
而doFilterInternal是OncePerRequestFilter 中的一个抽象方法
阅读源码可知:
OncePerRequestFilter.doFilter方法中通过request.getAttribute判断当前过滤器是否已执行
若未执行过,则调用doFilterInternal方法,交由其子类实现
OncePerRequestFilter
顾名思义,它能够确保在一次请求中只通过一次filter,而不会重复执行
是由Spring提供的抽象类
package org.springframework.session.web.http; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; abstract class OncePerRequestFilter implements Filter { public static final String ALREADY_FILTERED_SUFFIX = ".FILTERED"; private String alreadyFilteredAttributeName = this.getClass().getName().concat(".FILTERED"); OncePerRequestFilter() { } public final void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws ServletException, IOException { if (request instanceof HttpServletRequest && response instanceof HttpServletResponse) { HttpServletRequest httpRequest = (HttpServletRequest)request; HttpServletResponse httpResponse = (HttpServletResponse)response; boolean hasAlreadyFilteredAttribute = request.getAttribute(this.alreadyFilteredAttributeName) != null; if (hasAlreadyFilteredAttribute) { filterChain.doFilter(request, response); } else { request.setAttribute(this.alreadyFilteredAttributeName, Boolean.TRUE); try { this.doFilterInternal(httpRequest, httpResponse, filterChain); } finally { request.removeAttribute(this.alreadyFilteredAttributeName); } } } else { throw new ServletException("OncePerRequestFilter just supports HTTP requests"); } } protected abstract void doFilterInternal(HttpServletRequest var1, HttpServletResponse var2, FilterChain var3) throws ServletException, IOException; public void init(FilterConfig config) { } public void destroy() { } }
常识上都认为,一次请求本来就只filter一次,为什么还要由此特别限定呢?
往往我们的常识和实际的实现并不真的一样,经过一番资料的查阅,此方法是为了兼容不同的web container
也就是说并不是所有的container都入我们期望的只过滤一次,servlet版本不同,执行过程也不同
因此,为了兼容各种不同运行环境和版本,默认filter继承OncePerRequestFilter是一个比较稳妥的选择。
人怂胆子小,手拿大刀跑。
分类:
java
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
2018-08-11 关于Ant脚本
2018-08-11 Maven
2016-08-11 window对象
2016-08-11 关于结构体指针与别名