views:

83

answers:

2

Hi All,

I have 2 filters in my application. Based on some condition, I want to choose whether to execute the second filter or not. Is there a way to do this?

I did some googling with no success. I want the request to continue without executing the second filter. Is that possible?

Any help will be appreciated.

+2  A: 

You can set an Attribute in your request and check it in your second filter.

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

You can simplify the code above like this :

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

This way you just check the presence of the attribute "executeSecondFilter"

Colin Hebert
Nice idea, but this example will throw NPE if the attribute is not set.
BalusC
@BalusC, That's why I put a `!= true`, but auto-unboxing won over Object comparison, now it's corrected :)
Colin Hebert
You could also use `Boolean.TRUE`. However, I personally find it plain ugly ;)
BalusC
I already felt really bad about writing `true` in a condition, and in a way `Boolean.TRUE` would make me feel worse. :P
Colin Hebert
Good work guys :) some fresh perspectives :)
Vanchinathan Chandrasekaran
+2  A: 

In addition to Colin's answer, there's another way: just don't call FilterChain#doFilter(), but RequestDispatcher#forward().

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

But this will skip all filters from current on, expect of the ones which are listening on <dispatcher>FORWARD</dispatcher>.

BalusC
Good solution. But, we thought we would do the attribute way, cos its little bit simpler.
Vanchinathan Chandrasekaran
You're welcome. This one would however be the only solution when the source code of the other filter is completely out of your control (3rd party and so on).
BalusC