简体   繁体   中英

Updating response after doFilter

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?

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.

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM