捕获并记录响应正文 [英] Capture and log the response body
问题描述
我有一个处理某些 HTTP 请求和响应的 servlet.我想在发送回客户端之前记录响应正文.有什么方法可以在响应主体作为 HttpServletResponse
对象从 servlet 发送之前捕获它?
I have a servlet that handle certain HTTP requests and responses. I want to log the response body before sending back to the client. Is there any way that I can capture the response body before it is send as a HttpServletResponse
object from the servlet?
推荐答案
如果我理解正确,您想记录响应 body 吗?这是一项非常昂贵的任务,但如果这是业务需求......
If I understand you correctly, you want to log the response body? That's a pretty expensive task, but if that's the business requirement...
正如@duffymo 所指出的,Filter
是一个合适的地方.您可以通过将传入的 ServletResponse
替换为 HttpServletResponseWrapper
实现,将 HttpServletResponse#getWriter()
替换为自己的实现,将响应正文复制到某个缓冲区中.使用替换的响应继续过滤器链后,只需记录副本.
As @duffymo pointed, a Filter
is a suitable place for this. You can capture the response body by replacing the passed-in ServletResponse
with a HttpServletResponseWrapper
implementation which replaces the HttpServletResponse#getWriter()
with an own implementation which copies the response body into some buffer. After continuing the filter chain with the replaced response, just log the copy.
以下是 doFilter()
方法的启动示例:
Here's a kickoff example how the doFilter()
method can look like:
public void doFilter(ServletRequest request, final ServletResponse response, FilterChain chain) throws IOException, ServletException {
final CopyPrintWriter writer = new CopyPrintWriter(response.getWriter());
chain.doFilter(request, new HttpServletResponseWrapper((HttpServletResponse) response) {
@Override public PrintWriter getWriter() {
return writer;
}
});
logger.log(writer.getCopy());
}
CopyPrintWriter
如下所示:
public class CopyPrintWriter extends PrintWriter {
private StringBuilder copy = new StringBuilder();
public CopyPrintWriter(Writer writer) {
super(writer);
}
@Override
public void write(int c) {
copy.append((char) c); // It is actually a char, not an int.
super.write(c);
}
@Override
public void write(char[] chars, int offset, int length) {
copy.append(chars, offset, length);
super.write(chars, offset, length);
}
@Override
public void write(String string, int offset, int length) {
copy.append(string, offset, length);
super.write(string, offset, length);
}
public String getCopy() {
return copy.toString();
}
}
将此过滤器映射到您希望为其记录响应的 url-pattern
上.请记住,不会以这种方式记录二进制/静态内容,如图像、CSS、JS 文件等.您想通过使用足够具体的 url-pattern
来排除它们,例如*.jsp
或仅在相关 servlet 的 servlet-name
上.如果您无论如何都想记录二进制/静态内容(我没有看到任何好处),那么您也需要以相同的方式替换 HttpServletResponse#getOutputStream()
.
Map this filter on an url-pattern
for which you'd like to log responses for. Keep in mind that binary/static content like images, CSS, JS files and so on won't be logged this way. You'd like to exclude them by using a specific enough url-pattern
, e.g. *.jsp
or just on the servlet-name
of the servlet in question. If you want to log binary/static content anyway (for which I don't see any benefit), then you need to replace the HttpServletResponse#getOutputStream()
the same way as well.
这篇关于捕获并记录响应正文的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!