如何读取HttpServletResponse的输出流?

27

我想创建一个Servlet过滤器,它能够在Response被处理和完成后读取内容,并以XML或PDF等格式返回该信息。但我不确定如何从HttpServletResponse对象中获取任何信息。我该如何获取这些信息呢?

4个回答

29
将此添加到筛选Java文件中。
static class MyHttpServletResponseWrapper 
  extends HttpServletResponseWrapper {

  private StringWriter sw = new StringWriter(BUFFER_SIZE);

  public MyHttpServletResponseWrapper(HttpServletResponse response) {
    super(response);
  }

  public PrintWriter getWriter() throws IOException {
    return new PrintWriter(sw);
  }

  public ServletOutputStream getOutputStream() throws IOException {
    throw new UnsupportedOperationException();
  }

  public String toString() {
    return sw.toString();
  }
}

请使用以下代码:
HttpServletResponse httpResponse = (HttpServletResponse) response;
MyHttpServletResponseWrapper wrapper = 
  new MyHttpServletResponseWrapper(httpResponse);

chain.doFilter(request, wrapper);

String content = wrapper.toString();

现在,content变量具有输出流。您也可以对二进制内容执行此操作。


1
使用Servlet Reponse Wrapper并在输出时捕获它应该是最好的方法,我认为。 - DyreSchlock
1
处理请求的代码正在使用输出流。可以使用TeeOutputStream。(http://commons.apache.org/io/apidocs/org/apache/commons/io/output/TeeOutputStream.html) - DyreSchlock
5
BUFFER_SIZE的合理值是多少? - asgs
1
已经创建了LoggingFilter实现了Filter,进行了注册,但使用您的代码后它并没有起作用,只是在输出中出现了空字符串。您能否展示完整(已完成)版本的代码? - user2602807

5

Spring现在拥有这个功能。你只需要使用[ContentCachingResponseWrapper],它有一个public byte[] getContentAsByteArray()的方法。

我建议创建一个WrapperFactory,允许将其配置为使用默认的ResponseWrapper或ContentCachingResponseWrapper。


1

我不太确定您是否可以直接从HttpServletResponse对象中获取数据。更好的方法可能是构建您的应用程序,使请求被代理到适当的处理程序,并使用数据传输对象进行传递,从而可以构建适当的最终响应。通过这种方式,您永远不会修改多个响应对象或需要从其中读取。

虽然不是直接的答案,但这就是我给出这个问题的方式。


1
最终,我会做同样的事情,并使自己处于不必阅读响应的位置。但是,实际的请求处理使用的是相当封闭的黑盒子,不能被干扰 :/ - DyreSchlock

1

我不相信你可以这样做,因为写入输出流可能会导致数据在填充后调用任何servlet过滤器之前刷新到客户端。正如iftrue所建议的那样,建议采用不同的架构,生成您的XML(例如),然后以您想要的任何输出格式重新生成。

编辑:阅读了您对iftrue帖子的回复后,如果您真的不能干扰当前的处理过程,也许您需要一个servlet来代理您的请求,捕获原始输出,然后根据需要进行修改。非常糟糕,但是 :-(


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接