您的位置:首页 > 编程语言 > Java开发

Spring的OncePerRequestFilter的作用

2018-02-06 14:58 363 查看
在spring中,filter都默认继承OncePerRequestFilter,但为什么要这样呢?

 

OncePerRequestFilter顾名思义,他能够确保在一次请求只通过一次filter,而不需要重复执行。

 

Java代码  


public final void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)  

            throws ServletException, IOException {  

  

        if (!(request instanceof HttpServletRequest) || !(response instanceof HttpServletResponse)) {  

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

        }  

        HttpServletRequest httpRequest = (HttpServletRequest) request;  

        HttpServletResponse httpResponse = (HttpServletResponse) response;  

  

        String alreadyFilteredAttributeName = getAlreadyFilteredAttributeName();  

        if (request.getAttribute(alreadyFilteredAttributeName) != null || shouldNotFilter(httpRequest)) {  

            // Proceed without invoking this filter...  

            filterChain.doFilter(request, response);  

        }  

        else {  

            // Do invoke this filter...  

            request.setAttribute(alreadyFilteredAttributeName, Boolean.TRUE);  

            try {  

                doFilterInternal(httpRequest, httpResponse, filterChain);  

            }  

            finally {  

                // Remove the "already filtered" request attribute for this request.  

                request.removeAttribute(alreadyFilteredAttributeName);  

            }  

        }  

    }  

 

大家常识上都认为,一次请求本来就只过一次,为什么还要由此特别限定呢,呵呵实际上我们常识和实际的实现并不真的一样,经过一番查阅后,此方式是为了兼容不同的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是一个比较稳妥的选择。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  spring filter