使用 Spring MVC HandlerInterceptorAdapter 从 HttpServletResponse 记录响应体 (HTML) [英] Logging response body (HTML) from HttpServletResponse using Spring MVC HandlerInterceptorAdapter

查看:39
本文介绍了使用 Spring MVC HandlerInterceptorAdapter 从 HttpServletResponse 记录响应体 (HTML)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to log (just to console write now for simplicity sake) the final rendered HTML that will be returned by the HttpServletResponse. (i.e. the body) To this end, I am using the HandlerInterceptorAdapter from Spring MVC like so:

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 响应标头.我的问题是,是否有一种相对简单的方法可以将整个响应正文(即最终呈现的 HTML)记录到控制台,而无需借助 PrintWriter、OutputStream 等进行跳转.

This works as expected and I see the HTTP response headers in the console. My question is if there is a relatively simple way to log the entire response body (i.e. final rendered HTML) to the console without having to resort to doing jumping jacks with PrintWriters, OutputStream's and the like.

提前致谢.

推荐答案

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

This would be better done using a Servlet Filter rather than a Spring HandlerInterceptor, for the reason that a Filter is allowed to substitute the request and/or response objects, and you could use this mechanism to substitute the response with a wrapper which logs the response output.

这将涉及编写<的子类code>HttpServletResponseWrapper,覆盖 getOutputStream(也可能是 getWriter()).这些方法将返回 OutputStream/PrintWriter 实现,除了发送到其原始目的地之外,这些实现还将响应流吸入日志.一个简单的方法是使用 TeeOutputStream 来自 Apache Commons IO,但实现起来并不难自己.

This would involve writing a subclass of HttpServletResponseWrapper, overriding getOutputStream (and possibly also getWriter()). These methods would return OutputStream/PrintWriter implementations that siphon off the response stream into a log, in addition to sending to its original destination. An easy way to do this is using TeeOutputStream from Apache Commons IO, but it's not hard to implement yourself.

这是您可以做的事情的一个例子,利用 Spring 的 GenericFilterBeanDelegatingServletResponseStream,以及 TeeOutputStream,让事情变得更简单:

Here's an example of the sort of thing you could do, making use of Spring's GenericFilterBean and DelegatingServletResponseStream, as well as TeeOutputStream, to make things 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;
   }
}

这会将所有内容记录到 STDOUT.如果你想记录到一个文件,它会变得更加复杂,确保流关闭等等,但原理保持不变.

This logs everything to STDOUT. If you want to log to a file, it'll get a big more complex, what with making sure the streams get closed and so on, but the principle remains the same.

这篇关于使用 Spring MVC HandlerInterceptorAdapter 从 HttpServletResponse 记录响应体 (HTML)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆