2

I wish to add a HTTP header after the doFilter() function has finished running.

public void doFilter(ServletRequest request, ServletResponse response,
                     FilterChain chain) throws IOException, ServletException {
  HttpServletResponse httpResp = (HttpServletResponse) response;

  try {
    chain.doFilter(request, httpResp);

  } finally {           
    httpResp.setHeader("ADD A HEADER: ", "HEADER");
  }                                     
}

It seems that doFilter flushes the response.


UPDATE:

Thanks. After viewing IgorMadjeric and richardtz answers I decided to try Response wrapper:


This is the wrapper:

public class BufferedHttpServletResponse extends HttpServletResponseWrapper {

public BufferedHttpServletResponse(HttpServletResponse response) {
    super(response);
}

public void flushBuffer() {
    System.out.println("flush");
}

}

This is the Altered code:

public void doFilter(ServletRequest request, ServletResponse response,
                     FilterChain chain) throws IOException, ServletException {
    HttpServletResponse httpResp = (HttpServletResponse) response;

    try {
        BufferedHttpServletResponse bufferedResponse = new BufferedHttpServletResponse(httpResp);
        chain.doFilter(request, bufferedResponse);

    } finally {         
        bufferedResponse.setHeader("ADD A HEADER: ", "HEADER");
    }                                       
}

Still does not working. Did I do something wrong?

Predrag Maric
  • 23,938
  • 5
  • 52
  • 68
Ido Barash
  • 4,856
  • 11
  • 41
  • 78
  • 1
    Why do you need to do it after `doFilter()`? – axtavt Oct 02 '12 at 07:19
  • I want to add performance data and it seems to be tha right place to do it. – Ido Barash Oct 02 '12 at 07:29
  • I've had similar issue adding performance information. It may depend on the container when to commit the response, and you may not be able to control it. What I finally did was add the information in an html coment (it was html what i was generating) to the body of the response. Also, the performance information was only generated when certain parameter came in the request. – richardtz Oct 02 '12 at 15:32
  • @IdoBarash Did you get the answer? If yes can you paste it here? – prashanth-g Sep 27 '16 at 13:03
  • You can refer to this answer - https://stackoverflow.com/questions/32829124/adding-header-in-response-in-filter/32830377#32830377 – Harshad Vyawahare Oct 16 '18 at 14:56

3 Answers3

3

you cannot modify the response of the header once it has been flushed/commited (it has already been sent to the client).

doFilter does not flush the response, but many things in the execution of the request may cause it. (explicit call to response.flush(), too large body in the response), and you cannot control it.

However, you can use a HttpServletResponseWrapper to change this.

Hope it helps.

richardtz
  • 4,993
  • 2
  • 27
  • 38
  • I need to set response headers depending on content-type. Any thoughts on how to do so? – Arjun Mar 26 '15 at 05:44
  • @Arjun, you can set headers right after setting the content-type (content-type is also a header, so if you can set it, you will able to set other headers too) – richardtz Mar 26 '15 at 14:17
  • I want to set response header only if the content-type is "text/html". I'm not setting content-type in my code. I'm setting cache-control. – Arjun Mar 30 '15 at 06:15
  • Guys check http://stackoverflow.com/a/20555802/3884173 for setting the header by getting the response object anywhere(Even in POJO!) – prashanth-g Sep 27 '16 at 14:05
1

As already mentioned in the comments and in this question it might not be enough to overwrite flushBuffer(), but you need to also overwrite getWriter() and getOutputStream(). In certain cases even that might not be enough. For instance if the sendError(int) is called on the response it can also get commited.

Community
  • 1
  • 1
user1587520
  • 3,777
  • 1
  • 21
  • 20
0

In your case from code which you have posted, you can not to say:

It seems that doFilter flushes the response.

There is some rules about committing response.

Response is probably already committed by some component after you filter.

If you want to avoid this behavior you should use Request/Response wrappers, this will prevent components, on which your filter is applied to commit response.

IgorMadjeric
  • 389
  • 2
  • 3
  • Thanks, tried it and it didnt work. I updated the question's body. – Ido Barash Oct 02 '12 at 07:42
  • Response is not committed only if the flush method is called. Also when buffer is full the response will be automatically committed. Think about overwriting getOutputStream() and getWriter() method too – IgorMadjeric Oct 02 '12 at 13:21