【问题标题】:How can I read an HttpServletReponses output stream?如何读取 HttpServletReponses 输出流?
【发布时间】:2010-10-16 15:29:41
【问题描述】:

我想制作一个 Servlet 过滤器,它会在响应被处理和完成后读取它的内容,并以 XML 或 PDF 或其他格式返回该信息。但我不确定如何从 HttpServletResponse 对象中获取任何信息。我如何获得这些信息?

【问题讨论】:

    标签: java http servlets


    【解决方案1】:

    将此添加到过滤器 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();
    

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

    【讨论】:

    • 是的,我认为使用 Servlet 响应包装器并在编写输出时捕获输出是最好的方法。
    • 处理请求的代码使用的是输出流。可以使用 TeeOutputStream。 (commons.apache.org/io/apidocs/org/apache/commons/io/output/…)
    • BUFFER_SIZE 的合理值是多少?
    • 已经创建了 LoggingFilter 实现了过滤器,注册了它,使用你的代码,它不起作用,只是在退出时 emtry 字符串。你能显示完整(完成)的版本代码吗?
    【解决方案2】:

    Spring 现在有了它的功能。您需要做的就是使用 [ContentCachingResponseWrapper],它具有 public byte[] getContentAsByteArray() 方法。

    我建议让 WrapperFactory 允许使其可配置,无论是使用默认的 ResponseWrapper 还是 ContentCachingResponseWrapper。

    【讨论】:

      【解决方案3】:

      我不太了解您可以从 HttpServletResponse 对象中获取数据。构建您的应用程序可能更有意义,以便将请求代理到适当的处理程序并与数据传输对象一起传递,您可以从中构建适当的最终响应。通过这种方式,您永远不会修改多个响应对象或需要读取这些对象。

      我知道,这不是一个直接的答案,但这就是我提出问题的方式。

      【讨论】:

      • 最终,我会做同样的事情,让自己处于无需阅读回复的位置。但是我使用的实际请求处理是相当黑盒的,不能被弄乱:/
      【解决方案4】:

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

      编辑:在阅读了您对 iftrue 帖子的回复后,如果您真的不能干扰当前的处理,也许您需要一个 servlet 来代理您的请求,从原始输出中捕获输出,然后酌情处理。非常讨厌,但是:-(

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-09-02
        • 2012-04-09
        • 1970-01-01
        • 1970-01-01
        • 2017-04-14
        • 1970-01-01
        相关资源
        最近更新 更多