阅读到有关过滤器Filter的内容时
总会看到有两种过滤方法
doFilter和doFilterInternal
doFilter一看就知道是个过滤方法
doFilterInternal的Internal意思是内部的
所以内部的过滤方法是个什么鬼???
搜了半天没找到很直接的对比解释,自己翻翻源码看看,记录下
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是一个比较稳妥的选择。
————————————————
摘录自:https://blog.csdn.net/u013089490/java/article/details/84878319
以后再看到这两个方法名,就基本能分清楚了