使用Spring MVC HandlerInterceptorAdapter从HttpServletResponse记录响应主体(HTML)

csa*_*uel 26 java spring servlets spring-mvc

我正在尝试记录(仅为了简单起见,现在是控制台写入)最终呈现的HTML将由HttpServletResponse返回.(即正文)为此,我使用Spring MVC中的HandlerInterceptorAdapter,如下所示:

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

这按预期工作,我在控制台中看到HTTP响应头.我的问题是,是否有一种相对简单的方法可以将整个响应体(即最终呈现的HTML)记录到控制台,而无需使用PrintWriters,OutputStream等进行跳跃.

提前致谢.

ska*_*man 21

使用Servlet Filter而不是Spring 可以做得更好HandlerInterceptor,原因Filter是允许a 替换请求和/或响应对象,并且可以使用此机制用记录响应输出的包装器替换响应.

这将涉及编写一个子类HttpServletResponseWrapper,覆盖getOutputStream(也可能还getWriter()).除了发送到其原始目的地之外,这些方法还将返回OutputStream/ PrintWriter实现从响应流中虹吸到日志中.一个简单的方法来做到这一点是使用TeeOutputStreamApache的共享IO,但它并不难实现自己.

这里是那种你可以做的事情的一个例子,利用Spring的中GenericFilterBeanDelegatingServletResponseStream,以及TeeOutputStream,使事情变得更加简单:

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;
   }
}
Run Code Online (Sandbox Code Playgroud)

这会将所有内容记录到STDOUT.如果你想登录一个文件,它会变得更复杂,确保流关闭等等,但原则仍然是一样的.


Zor*_*art 9

如果你正在使用(或考虑)logback作为你的日志记录框架,那么有一个很好的servlet过滤器就可以完成.查看文档中的TeeFilter章节.


小智 6

我一直在寻找一种方法来记录完整的HTTP请求/响应一段时间,并发现它已经在Tomcat 7 RequestDumperFilter中为我解决了.它的工作方式与Tomcat 7容器中的广告相同.如果你想在Jetty中使用它,这个类可以很好地独立运行,或者像我一样,复制并适应我环境的特定需求.