Friday, June 1, 2012

Using HttpServletResponseWrapper to Modify Response Already Written


HttpServletResponseWrapper can be used when you need to capture all the response that is already written by the Servlet or other Filters, and then modifying it. For example, if you need to replace some things in the response, you can first use HttpServletResponseWrapper to capture all the existing response in a ByteArrayOutputStream. After this is collected, you can then do the necessary manipulation and respond to user.

This needs to be done in a Filter, and you'll also have to sub-class the HttpServletResponseWrapper. The call flow will be as follows:
  1. Processing arrives at the Filter.
  2. Filter creates the subclassed HttpServletResponseWrapper and puts it through the Filter chain.
  3. All responses from that point onwards are written to the ByteArrayOutputStream instead of the Servlet's PrintWriter.
  4. When the Filter chain returns, take the ByteArrayOutputStream, extract the response already written, modify it, and then send the modified response back to the client via the Servlet's PrintWriter.
Example code for HttpServletResponseWrapper sub-class:

public class ExampleResponseWrapper extends HttpServletResponseWrapper {
    private PrintWriter w = null;
    private ByteArrayOutputStream os = null;
    public ExampleResponseWrapper(HttpServletResponse response) {
        super(response);
        os = new ByteArrayOutputStream();
        w = new PrintWriter(os);
    }
    @Override
    public PrintWriter getWriter() throws IOException {
        return w;
    }
    public String getOutput() {
        w.flush();
        w.close();
        return os.toString();
    }
}
Example code in the Filter:
ExampleResponseWrapper wrappedResp = new ExampleResponseWrapper((HttpServletResponse)resp);
filterChain.doFilter(req, wrappedResp);
String wrappedOutput = wrappedResp.getOutput();

And then manipulate the output and send back to client.

No comments:

Post a Comment