java - 捕获并记录响应正文

标签 java servlets

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

最佳答案

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

正如@duffymo 指出的那样,Filter 是一个合适的地方。您可以通过将传入的 ServletResponse 替换为 HttpServletResponseWrapper 来捕获响应正文。将 HttpServletResponse#getWriter() 替换为自己的实现,该实现将响应主体复制到某个缓冲区中。使用替换后的响应继续过滤器链后,只需记录副本即可。

下面是 doFilter() 方法的启动示例:

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()

关于java - 捕获并记录响应正文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3242236/

相关文章:

java - 部署项目到tomcat ROOT

java - Sql事件与Servlet中的ScheduledExecutorService

java - 经过几次相同的 hql 查询后,应用程序卡住

带点的Java数组(协调)

java - 将滚动条监听器添加到 JOGL 项目

java - 如何在控制台上显示 maven-surefire-plugin 单元测试覆盖率报告

java - 如何使用顶点在 opengles 中移动对象?

java - 将域名插入 servlet 身份验证 token

java - 使用 Stripe 时 Maven 编译错误 : Cannot find symbol APIException, APIConnectionException

android - GCM 演示不会在服务器和应用重启时接受消息