捕获并记录响应正文 [英] Capture and log the response body

查看:96
本文介绍了捕获并记录响应正文的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个处理某些HTTP请求和响应的servlet。我想在发送回客户端之前记录响应正文。有没有什么方法可以在从servlet作为 HttpServletResponse 对象发送之前捕获响应主体?

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?

推荐答案

如果我理解正确,您想记录响应正文?这是一项相当昂贵的任务,但如果这是业务需求...

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指出的那样,过滤器是一个合适的地方。您可以通过使用 ServletResponse 来捕获响应正文/servlet/http/HttpServletRequestWrapper.html\"rel =noreferrer> 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屋!

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