【问题标题】:How to skip a filter in the filter chain in java如何在java中跳过过滤器链中的过滤器
【发布时间】:2011-04-13 21:10:34
【问题描述】:

我的应用程序中有 2 个过滤器。根据某些条件,我想选择是否执行第二个过滤器。有没有办法做到这一点?

我做了一些谷歌搜索,但没有成功。我希望请求继续而不执行第二个过滤器。这可能吗?

任何帮助将不胜感激。

【问题讨论】:

    标签: java servlets servlet-filters


    【解决方案1】:

    除了科林的回答,还有一个办法:就是不要叫FilterChain#doFilter(),而是RequestDispatcher#forward()

    if (condition) {
        request.getRequestDispatcher(((HttpServletRequest) request).getServletPath()).forward(request, response);
    } else {
        chain.doFilter(request, response);
    }
    

    但这将从当前开始跳过所有过滤器,除了那些正在收听<dispatcher>FORWARD</dispatcher>的过滤器。

    【讨论】:

    • 很好的解决方案。但是,我们认为我们会使用属性方式,因为它更简单一些。
    • 不客气。然而,当另一个过滤器的源代码完全不受您的控制(第 3 方等)时,这将是唯一的解决方案。
    • 上面的例子忘记了基本 servlet 路径之后的 URL 部分。这将解决这个问题: request.getRequestDispatcher(((HttpServletRequest) request).getServletPath() + StringUtils.defaultString(((HttpServletRequest)request).getPathInfo()) ).forward(request, response);
    • Cojones 提出了一个很好的观点。根据您的应用程序,您可能需要请求的更多部分,而不仅仅是 servlet 路径。这个 StackOverflow 答案有一个很好的表格,显示请求的哪些部分是:stackoverflow.com/a/21046620/224354
    • 非常感谢这个解决方案!
    【解决方案2】:

    您可以在您的请求中设置一个属性并在您的第二个过滤器中检查它。

    public class FirstFilter implements Filter {
        //...
    
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            servletRequest.setAttribute("executeSecondFilter", true);
            //...
            if(someReason)
                servletRequest.setAttribute("executeSecondFilter", false);
            filterChain.doFilter(servletRequest, servletResponse);
        }
    }
    
    public class SecondFilter implements Filter {
        //..
    
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            if (servletRequest.getAttribute("executeSecondFilter") == null || !((Boolean) servletRequest.getAttribute("executeSecondFilter"))) {
                filterChain.doFilter(servletRequest, servletResponse);
            }
            //...
        }
    }
    

    你可以像这样简化上面的代码:

    public class FirstFilter implements Filter {
        //...
    
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            //...
            if(someReason)
                servletRequest.setAttribute("executeSecondFilter", false);
            filterChain.doFilter(servletRequest, servletResponse);
        }
    }
    
    public class SecondFilter implements Filter {
        //..
    
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            if (servletRequest.getAttribute("executeSecondFilter") != null) {
                filterChain.doFilter(servletRequest, servletResponse);
            }
            //...
        }
    }
    

    这样你只需检查属性“executeSecondFilter”的存在

    【讨论】:

    • 好主意,但如果未设置属性,此示例将抛出 NPE。
    • @BalusC,这就是为什么我放了一个!= true,但是自动拆箱胜过对象比较,现在它已经更正了:)
    • 您也可以使用Boolean.TRUE。但是,我个人觉得它很丑;)
    • 我已经对在某种条件下写true 感到非常难过,在某种程度上Boolean.TRUE 会让我感觉更糟。 :P
    • @ColinHebert 。你好!你对他的问题有什么解决方案吗:stackoverflow.com/questions/53774909/…
    猜你喜欢
    • 2012-10-27
    • 2015-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-21
    • 2022-10-23
    • 1970-01-01
    • 2011-12-14
    相关资源
    最近更新 更多