OncePerRequestFilter的作用


在spring中,filter都默認繼承OncePerRequestFilter,但為什么要這樣呢?

OncePerRequestFilter顧名思義,他能夠確保在一次請求只通過一次filter,而不需要重復執行。

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;
            String alreadyFilteredAttributeName = this.getAlreadyFilteredAttributeName();
            boolean hasAlreadyFilteredAttribute = request.getAttribute(alreadyFilteredAttributeName) != null;
            if(!hasAlreadyFilteredAttribute && !this.skipDispatch(httpRequest) && !this.shouldNotFilter(httpRequest)) {
                request.setAttribute(alreadyFilteredAttributeName, Boolean.TRUE);

                try {
                    this.doFilterInternal(httpRequest, httpResponse, filterChain);
                } finally {
                    request.removeAttribute(alreadyFilteredAttributeName);
                }
            } else {
                filterChain.doFilter(request, response);
            }

        } else {
            throw new ServletException("OncePerRequestFilter just supports HTTP requests");
        }
    }

常識上都認為,一次請求本來就只過一次,為什么還要由此特別限定呢,實際上此方式是為了兼容不同的web container,特意而為之(jsr168),

也就是說並不是所有的container都像我們期望的只過濾一次,servlet版本不同,表現也不同

/**
* Filter base class that guarantees to be just executed once per request,
* on any servlet container. It provides a {@link #doFilterInternal}
* method with HttpServletRequest and HttpServletResponse arguments.
*
* <p>The {@link #getAlreadyFilteredAttributeName} method determines how
* to identify that a request is already filtered. The default implementation
* is based on the configured name of the concrete filter instance.
*
* @author Juergen Hoeller
* @since 06.12.2003
*/

如,servlet2.3與servlet2.4也有一定差異 

在servlet-2.3中,Filter會過濾一切請求,包括服務器內部使用forward轉發請求和<%@ include file="/index.jsp"%>的情況。

到了servlet-2.4中Filter默認下只攔截外部提交的請求,forward和include這些內部轉發都不會被過濾,但是有時候我們需要 forward的時候也用到Filter。

因此,為了兼容各種不同的運行環境和版本,默認filter繼承OncePerRequestFilter是一個比較穩妥的選擇


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM