如何在java中跳过过滤器链中的过滤器

Posted

技术标签:

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

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

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

任何帮助将不胜感激。

【问题讨论】:

【参考方案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 路径。这个 *** 答案有一个很好的表格,显示请求的哪些部分是:***.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 。你好!你对他的问题有什么解决方案吗:***.com/questions/53774909/…

以上是关于如何在java中跳过过滤器链中的过滤器的主要内容,如果未能解决你的问题,请参考以下文章

spring cloud gateway 某些路由中跳过全局过滤器

如何在 Java/Scala 中跳过流中的无效字符?

如何创建多个异步java过滤器?

关于java,过滤html请求的Filter中跳转页面的问题。

如何在 Fortran 90 中跳过带有“#”符号的行? [复制]

如何从mysql中的表中跳过行