Question

Imagine, that one day you would come across two servlet filters, one extending the other like this:

public class MainFilter implements Filter{
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain){
         .... some stuff ...
       chain.doFilter(request, response);
    }
}

public class FilterExtended extends MainFilter{
     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain){

       // Is the following code mentally ok?
       if(some business condition){
          {    
              super.doFilter(request, response, chain); // we call MainFilter.doFilter(), which as a consequence calls chain.doFilter()
              return;
          }

       chain.doFilter(request, response); // let the request pass through
    }
}

My question is if it is a good practice to even think about inheriting servlet filters like that. I wasn't able to find any information on the internet regarding this.

I personally think that filters should not be in some horrendous class hierarchies, they should stay separately (which is easier for my brain to grasp and is easier to see the filters attached in the web.xml), but I would like to know some other opinions before doing any code changes.

Was it helpful?

Solution

That kind of abstraction would be useful for handling any kind of cross-cutting concerns, similar to aspects.

For example, I might want all my filters to log that they are being applied to the request and then log any exceptions that passed by them so that I can know for any given request which filters acted on it. To put the exact same logging code in all of my filters would be a violation of DRY. To try and hook aspects into filters would be overly complicated. I cannot think of a better way than inheritance to achieve that goal.

Another example is that I might have a set of filters which are only applied to certain users or types of requests. A simple base filter class which had an abstract getUsersToApplyFor() would make that very easy to implement.

What I would NOT use this approach for is to setup custom filter chains through inheritance. For example, I would not create a base class which modified the request and response in one way and a child class which then additionally modified the request and response in another way, and the two modifications are unrelated to each other. As you pointed out, that would be better left in the web.xml where it would be clearer for future developers.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top