我正在尝试登录(为简单起见,现在只是控制台控制台编写)最终呈现的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());
    }
}

这按预期工作,并且我在控制台中看到HTTP响应 header 。我的问题是,是否有一种相对简单的方法将整个响应正文(即最终呈现的HTML)记录到控制台,而不必诉诸于PrintWriters,OutputStream之类的方法。

提前致谢。

最佳答案

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

这将涉及编写 HttpServletResponseWrapper 的子类,覆盖getOutputStream(可能还包括getWriter())。这些方法将返回OutputStream/PrintWriter实现,这些实现除了将响应流发送到其原始目的地之外,还将响应流虹吸到日志中。一种简单的方法是使用 TeeOutputStream 中的Apache Commons 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;
   }
}

这会将所有内容记录到STDOUT。如果要登录到文件,它将变得更加复杂,要确保关闭流等等,但是原理保持不变。

10-06 07:27
查看更多