使用Spring MVC HandlerInterceptorAdapter从HttpServletResponse记录响应正文(HTML)
问题内容:
我正在尝试记录(为简单起见,现在只是控制台控制台编写)最终呈现的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响应标头。我的问题是,是否有一种相对简单的方法将整个响应正文(即最终呈现的HTML)记录到控制台,而不必诉诸于PrintWriters,OutputStream之类的方法。
提前致谢。
问题答案:
使用Servlet
Filter
而不是Spring
会更好HandlerInterceptor
,因为Filter
允许a
替换请求和/或响应对象,并且您可以使用此机制用记录响应输出的包装器替换响应。
这将涉及编写的子类HttpServletResponseWrapper
,并重写getOutputStream
(也可能是getWriter()
)。这些方法将返回OutputStream
/
PrintWriter
实现,除了将响应流发送到其原始目的地之外,还将响应流虹吸到日志中。一个简单的方法是TeeOutputStream
从Apache Commons
IO使用,但是实现自己并不难。
这是您可以做的事情的一个示例,利用Spring的GenericFilterBean
和DelegatingServletResponseStream
以及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。如果要登录到文件,它将变得更加复杂,要确保关闭流等等,但是原理保持不变。