D 的个人博客

开源程序员,自由职业者

小而美的 Java 博客系统 Solo
Golang 在线 IDE Wide
黑客与画家的社区 Sym
  menu
401 文章
1,867 评论
3398660 浏览
9 当前访客
ღゝ◡╹)ノ❤️

如何跳过过滤器处理?

假如应用中存在多个过滤器,如何在第一个过滤器处理时根据某些条件跳过后续过滤器处理?这里提供了两种方式来解决这个问题。

方式一:在后续过滤器中根据前面过滤器处理后设置的标识手动跳过。标识可以放在 Request Attributes 里。

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);
    }
    //...
}

}

方式二:过滤器处理时,不进行后续过滤器链处理(FilterChain#doFilter()),而是直接转发请求给 Servlet(RequestDispatcher#forward())。

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

这样会跳过后续的所有过滤器处理,如果有某个过滤器仍然需要进行处理,那可以在 web.xml 中配置该过滤器 <filter-mapping>:

<dispatcher>FORWARD</dispatcher>

细节可参阅 Servlet 3.0 规范(JSR-315)6.2.5 Filters and the RequestDispatcher

 

参考:

 
评论
  • 学习了,感觉非常好!

    Reply
  • Ec

    学习了,刚好碰到这个问题,需要跳过struts的filter,来实现某些功能,用的是方法二,不过 request.getRequestDispatcher(httpServletRequest.getServletPath() + httpServletRequest.getPathInfo()).forward(request, response);

    getPathInfo()不知道什么用,加了以后有问题,所以用的 是

    request.getRequestDispatcher(httpServletRequest.getServletPath() ).forward(request, response);

    Reply
  • 唉,只懂肤浅的java

    Reply