29

I want to make a Servlet filter that will read the contents of the Response after it's been processed and completed and return that information in XML or PDF or whatever. But I'm not sure how to get any information out of the HttpServletResponse object. How can I get at this information?

4 Answers 4

30

Add this to the filter java file.

static class MyHttpServletResponseWrapper 
  extends HttpServletResponseWrapper {

  private StringWriter sw = new StringWriter(BUFFER_SIZE);

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

  public PrintWriter getWriter() throws IOException {
    return new PrintWriter(sw);
  }

  public ServletOutputStream getOutputStream() throws IOException {
    throw new UnsupportedOperationException();
  }

  public String toString() {
    return sw.toString();
  }
}

Use the follow code:

HttpServletResponse httpResponse = (HttpServletResponse) response;
MyHttpServletResponseWrapper wrapper = 
  new MyHttpServletResponseWrapper(httpResponse);

chain.doFilter(request, wrapper);

String content = wrapper.toString();

The content variable now has the output stream. You can also do it for binary content.

Sign up to request clarification or add additional context in comments.

4 Comments

Yeah, using an Servlet Reponse Wrapper and capturing output when it's written is about the best way to do it, I think.
The code that handles the request is using the output stream though. The TeeOutputStream can be used. ( commons.apache.org/io/apidocs/org/apache/commons/io/output/… )
what's a reasonable value of BUFFER_SIZE?
Have created LoggingFilter implements Filter, registered it, use your code and it does not work, just emtry strings on the exit. Could you show full (completed) version code?
5

Spring now has feature for it . All you need to do is use [ContentCachingResponseWrapper], which has method public byte[] getContentAsByteArray() .

I Suggest to make WrapperFactory which will allow to make it configurable, whether to use default ResponseWrapper or ContentCachingResponseWrapper.

1 Comment

1

I don't much know that you can get data out of an HttpServletResponse object as such. It may make more sense to structure your application such that requests are proxied to the appropriate handlers and passed about with data transfer objects, from which you can build the appropriate final response. In this manner, you never modifiy more than one response object or need to read from such.

Not a direct answer, I know, but that's how I'd do it give the question.

1 Comment

Ultimately, I'd do the same thing and put myself in a position where I wouldn't have to read for the response. But the actually request processing I'm using is fairly black boxed and can't be messed with :/
1

I don't believe you can necessarily do this given that writing to the output stream may result in the data being flushed to the client prior to any servlet filters being invoked post-population. As iftrue suggests, a different architecture would be advisable, to generate your XML (say) and then regenerate in whatever output format you desire.

EDIT: Having read your response to iftrue's posting, if you really can't interfere with the current processing, perhaps you require a servlet to proxy your request, capture the output from the original output, and then munge as appropriate. Very nasty, however :-(

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.