【Filter概念】doFilter和doFilterInternal的區(qū)別

閱讀到有關(guān)過濾器Filter的內(nèi)容時
總會看到有兩種過濾方法
doFilter和doFilterInternal

doFilter一看就知道是個過濾方法
doFilterInternal的Internal意思是內(nèi)部的
所以內(nèi)部的過濾方法是個什么鬼???
搜了半天沒找到很直接的對比解釋,自己翻翻源碼看看,記錄下

doFilter是整個過濾器最底層的概念Filter接口中的方法
所有過濾器都要實現(xiàn)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判斷當前過濾器是否已執(zhí)行
若未執(zhí)行過,則調(diào)用doFilterInternal方法,交由其子類實現(xiàn)

OncePerRequestFilter
顧名思義,它能夠確保在一次請求中只通過一次filter,而不會重復(fù)執(zhí)行
是由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一次,為什么還要由此特別限定呢?
往往我們的常識和實際的實現(xiàn)并不真的一樣,經(jīng)過一番資料的查閱,此方法是為了兼容不同的web container
也就是說并不是所有的container都入我們期望的只過濾一次,servlet版本不同,執(zhí)行過程也不同
因此,為了兼容各種不同運行環(huán)境和版本,默認filter繼承OncePerRequestFilter是一個比較穩(wěn)妥的選擇。
————————————————
摘錄自:https://blog.csdn.net/u013089490/java/article/details/84878319

以后再看到這兩個方法名,就基本能分清楚了

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容