mvc interceptores handlerinterceptoradapter annotation java spring spring-mvc servlets

java - interceptores - Cuerpo de respuesta de registro(HTML) de HttpServletResponse utilizando Spring MVC HandlerInterceptorAdapter



session interceptor in spring mvc (4)

Estoy intentando iniciar sesión (solo para escribir en consola ahora por simplicidad) el HTML final que será devuelto por HttpServletResponse. (es decir, el cuerpo) Para este fin, estoy usando el HandlerInterceptorAdapter de Spring MVC de esta manera:

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

Esto funciona como se esperaba y veo los encabezados de respuesta HTTP en la consola. Mi pregunta es si hay una manera relativamente simple de registrar todo el cuerpo de la respuesta (es decir, el HTML final renderizado) en la consola sin tener que recurrir a hacer saltos con PrintWriters, OutputStream y similares.

Gracias por adelantado.


Esto se haría mejor usando un Servlet Filter lugar de un Spring HandlerInterceptor , por la razón de que un Filter puede sustituir los objetos de solicitud y / o de respuesta, y podría usar este mecanismo para sustituir la respuesta con un contenedor que registra la respuesta salida.

Esto implicaría escribir una subclase de HttpServletResponseWrapper , anulando getOutputStream (y posiblemente también getWriter() ). Estos métodos devolverían implementaciones de OutputStream / PrintWriter que PrintWriter la secuencia de respuesta en un registro, además de enviar a su destino original. Una forma fácil de hacerlo es usar TeeOutputStream de Apache Commons IO , pero no es difícil implementarlo usted mismo.

Aquí hay un ejemplo del tipo de cosas que podría hacer, utilizando Spring''s GenericFilterBean y DelegatingServletResponseStream , así como TeeOutputStream , para facilitar las cosas:

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; } }

Esto registra todo en STDOUT. Si desea iniciar sesión en un archivo, se volverá mucho más complejo, con lo que se asegurará de que las transmisiones se cierren, y así sucesivamente, pero el principio sigue siendo el mismo.


He estado buscando una forma de registrar la Solicitud / Respuesta HTTP completa por un tiempo y descubrí que se resolvió para mí en el Tomcat 7 RequestDumperFilter . Funciona como se anuncia desde un contenedor Tomcat 7. Si desea usarlo en Jetty, la clase funciona bien de forma independiente o, como lo hice, copiada y adaptada a las necesidades específicas de mi entorno.


Hice una pequeña biblioteca spring-mvc-logger disponible vía maven central.

Agregar a pom.xml:

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

Agregar a 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>

Agregar a log4j.xml:

<logger name="com.github.isrsal.logging.LoggingFilter"> <level value="DEBUG"/> </logger>


Si está utilizando (o considerando) el logback como su marco de trabajo de registro, ya hay un buen filtro de servlet disponible que hace exactamente eso. Consulte el capítulo de TeeFilter en la documentation .