Log (HTML) response form from HttpServletResponse using Spring MVC HandlerInterceptorAdapter

I am trying to enter (just to just write for simplicity) the final rendered HTML that will be returned by HttpServletResponse. (i.e. body). To this end, I use the HandlerInterceptorAdapter from Spring MVC as follows:

public class VxmlResponseInterceptor extends HandlerInterceptorAdapter { @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println(response.toString()); } } 

This works as expected, and I see the HTTP response headers in the console. My question is, is there a relatively simple way to register the entire response organ (i.e., the final rendered HTML) to the console without resorting to performing jumping sockets using PrintWriters, OutputStream, etc.

Thanks in advance.

+26
java spring spring-mvc servlets
Jan 28
source share
4 answers

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.

+21
Jan 31 '10 at 12:25
source

If you use (or consider) logback as your logging framework, there is already a good servlet filter that does exactly that. Check out the TeeFilter section in the documentation .

+9
Jan 31 '10 at 21:48
source

I was looking for a way to register a full HTTP request / response for a while and found that it was resolved for me in Tomcat 7 RequestDumperFilter . It works as advertised from the Tomcat 7 container. If you want to use it in Jetty, the class works perfectly autonomously or, like me, copied and adapted to the specific needs of my environment.

+6
Oct 29
source

I made a small spring-mvc-logger library, accessible through the maven central center.

Add to pom.xml:

 <dependency> <groupId>com.github.isrsal</groupId> <artifactId>spring-mvc-logger</artifactId> <version>0.2</version> </dependency> 

Add to web.xml:

 <filter> <filter-name>loggingFilter</filter-name> <filter-class>com.github.isrsal.logging.LoggingFilter</filter-class> </filter> <filter-mapping> <filter-name>loggingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> 

Add to log4j.xml:

 <logger name="com.github.isrsal.logging.LoggingFilter"> <level value="DEBUG"/> </logger> 
+1
Aug 22
source



All Articles