zoukankan      html  css  js  c++  java
  • 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是一个比较稳妥的选择。
  • 相关阅读:
    解决Android SDK Manager更新、下载速度慢
    selenium报错以及各解决方法
    webdriver对各种浏览器的支持
    selenium driver版本和Chrome浏览器版本对应关系
    selenium web driver
    js中变量注意事项
    js选项卡实现
    两种JS方法实现斐波那契数列
    三种JS方法确定元素在数组中的索引值
    javascript内置属性——arguments
  • 原文地址:https://www.cnblogs.com/sjxbg/p/13475387.html
Copyright © 2011-2022 走看看