This is best done using the Filter servlet rather than the Spring HandlerInterceptor , because a Filter allowed to replace request and / or response objects, and you can use this mechanism to substitute the response with a wrapper that records the response output.
This will involve writing a subclass of HttpServletResponseWrapper , overriding getOutputStream (and possibly also getWriter() ). These methods will return OutputStream / PrintWriter implementations that filter out the response stream in the log, in addition to sending to the original destination. An easy way to do this is the TeeOutputStream from Apache Commons IO , but it's not hard to implement on your own.
Here is an example of what you could do using Spring GenericFilterBean and DelegatingServletResponseStream as well as TeeOutputStream to make the task easier:
public class ResponseLoggingFilter extends GenericFilterBean { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException { HttpServletResponse responseWrapper = loggingResponseWrapper((HttpServletResponse) response); filterChain.doFilter(request, responseWrapper); } private HttpServletResponse loggingResponseWrapper(HttpServletResponse response) { return new HttpServletResponseWrapper(response) { @Override public ServletOutputStream getOutputStream() throws IOException { return new DelegatingServletOutputStream( new TeeOutputStream(super.getOutputStream(), loggingOutputStream()) ); } }; } private OutputStream loggingOutputStream() { return System.out; } }
This writes everything to STDOUT. If you want to enter a file, it will become more complicated to make sure that the threads are closed and so on, but the principle remains the same.
skaffman Jan 31 '10 at 12:25 2010-01-31 12:25
source share