Intercepting HTTP Response using Servlet Filter

Hello,
Servlet Filters are used to intercept the HTTP Requests/HTTP Responses.
Filters generally contain some logic that can be applied across a URL pattern.
I have used filters generally to verify if user is logged in or if user has appropriate privilege to access the resource.
While addressing such requirements we end up writing a Filter that is better known as Request Filter because it
intercepts the HTTP request. So most of the time when I ask someone if they know how to implement a HTTP Response Filter, they look puzzled. Of course,I too have gone through this situation in past.

Below is the sample code for Filter(Request Filter)  –

package com.amit.web.filter;

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class MyFilter implements Filter {

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// place your code here
 // pass the request along the filter chain
chain.doFilter(request, response);
}

public void init(FilterConfig arg0) throws ServletException {}
public void destroy() {}
}

You would know that the line “chain.doFilter(request,response)“, is responsible for executing the next Filter or web resource in line.
Hence if I map MyFilter for servlet named MyServlet then any request for MyServlet would be intercepted by MyFilter. When it encounters “chain.doFilter(request,response)“,it would call the MyServlet’s service method.
Once MyServlet has finished its task, the call to “doFilter” would return and if there is no code/logic written after this line, HTTP Response goes back to the client.
This precisely is the location where we can write the code that would alter the HTTP Response.
This means if we need to write a HTTP Response filter i.e. intercepting HTTP Response, then we need to write the business logic after “chain.doFilter(request,response)” and we are intercepting the HTTP response before it reaches the destination.  The method doFilter that would serve as HTTP Response filter is shown below –

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
chain.doFilter(request, response);
//PLACE YOUR CODE HERE THAT MODIFIES THE RESPONSE.
} 

Overall this is preety easy but usually goes unnoticed which is the reason I felt writing about this.

Another important point about Servlet Filters is –
Consider there are MyFilter1, MyFilter2 and MyFilter3 configured for any requests to Servlet MyServlet.
In this case MyFilter1, MyFilter2 and MyFilter3 will be executed in the order of configuration while intercepting the HTTP Requests.
While sending back the response they would be executed in the REVERSE order as shown in the diagram below.

Filter-Invocation-Sequence

Hope this helpes someone who is wondering how to implement HTTP Response Filters.Cheers !!
Amit

Advertisements

12 Responses to Intercepting HTTP Response using Servlet Filter

  1. Murugan says:

    Nice…..
    And thnx……

  2. kiran says:

    Thanks…this article was of great help

  3. Ranjan says:

    Thanks a ton.. It is really helpful.

  4. 2012cse says:

    Hey guys is it working?

  5. 2012cse says:

    @Amit I have added some code to change the response after

    chain.doFilter(…)

    like

    chain.doFilter(req, res);

    res.setHeader(“X-X”, “X-H”);

    But it is not working! Any suggestions?

    • Amit says:

      You would need to share the exception you are encountering if any. Moreover I believe any forum would be a good place to discuss this issue than here. ( StackOverflow, coderanch etc)

      On Tue, Sep 27, 2016 at 1:15 AM, Javanubhav (जावानुभव) wrote:

      >

  6. pdn1212 says:

    Just so you know, I got this blog URL straight out from IBM in responding to my question, which btw, I’ve searched the net to no avail. The details in your blog saved my day. Thanks.

  7. pdn1212 says:

    Hi Amit,

    I had succeeded in implementing response filter, as you had pointed out it’s very straight-forward.

    My target endpoint servlet has delay to hold up response. Many concurrent requests with long delay were requested, my servlet filter was able to detect that condition properly because the code after “chain.doFilter(req, res)” did NOT get executed until after endpoint servlet generate response only after the full delay expired.

    What strange now is that the code after “chain.doFilter(req, res)” got executed “IMMEDIATELY”, after some minor-and-cosmetics changes like adding traces to show the accumulative count of concurrent requests being held up by the delay period.

    I’ve review left-and-right the code changes and can’t figure out the root cause. Do you have any suggestions on how to RCA this?

    Thanks.

  8. pdn1212 says:

    Amit, I solved the issue by resuming my work from last working version. I had no time to do an RCA though I wanted to.

  9. Anup Kurian Alex says:

    The code snippet that you have mentioned (//PLACE YOUR CODE HERE THAT MODIFIES THE RESPONSE.) will have no impact on the response as you are not wrapping the response and passing the wrapped response into the chain. By the time chain.doFilter(request, response) finishes, the response stream is already closed.

    Please read the below article from Oracle http://docs.oracle.com/javaee/5/tutorial/doc/bnagb.html

    “A filter that modifies a response must usually capture the response before it is returned to the client. To do this, you pass a stand-in stream to the servlet that generates the response. The stand-in stream prevents the servlet from closing the original response stream when it completes and allows the filter to modify the servlet’s response.”

    • Amit says:

      I have not tried this for long time but if I remember right I think unless you have committed the response object you can continue modifying it.
      Please read the second line of the text that you have posted which also tries to say this.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: