统计写入Tomcat HttpServletResponse的实际字节数

4
我需要计算写入 HttpServletResponse 的实际字节数,以确保整个文件已经传输。我的天真做法如下:
            InputStream instream = InputStream instream = new FileInputStream("myfile.zip");
            ServletOutputStream outputStream = res.getOutputStream();

            CountingInputStream countingInputStream = new CountingInputStream(instream);
            IOUtils.copy(countingInputStream, outputStream);

            log.debug("Expected count: " + String.valueOf(contentLength));
            log.debug("getCount: " + countingInputStream.getCount());

            outputStream.close();
            countingInputStream.close();
            instream.close();

在Jetty上,这种方法运作良好,但是在Tomcat上,即使客户端取消了下载,Tomcat仍然返回完整的输出流以供编写。

此外,这种方法在Tomcat 6上多年来也一直表现良好。我们现在必须迁移到Tomcat 7并遇到了这个问题。

有没有一种方法可以计算实际发送到客户端的字节数?


尝试使用 byte[] bytes = IOUtils.toByteArray(inputStream); - Suzon
可能出现的情况是Tomcat 7(或中间的其他服务器)在将输出发送到客户端之前对其进行了缓冲。 - JoseM
@Suzon 这会导致字节流被缓冲在byte[]中。我们正在传输2GB的文件。如果它能工作,那么性能也不会很好。 - Randy
@JoseM 实际上我怀疑Tomcat会缓冲流,但我不太确定。此外,我不知道如何解决这个问题。 - Randy
这里有一个很好的例子:如何使用ArgumentCaptor验证写入HttpServletResponse的字节 - Suzon
@Suzon 谢谢你,但这基本上就是我已经在做的。 - Randy
1个回答

0

有几件事情需要调查:

  1. 是否提供了内容长度头?如果没有,Tomcat 将缓存整个响应。
  2. 确保容器配置支持分块编码。
  3. 确保客户端支持分块编码(它不是 HTTP 1.0)。

另一件事是,在版本 7.0.27 之后,Tomcat 流式传输基础设施在 WebSockets 实现中经历了重大的重构。有关更多详细信息,请参见此处:

http://www.tomcatexpert.com/blog/2012/05/01/how-apache-tomcat-implemented-websocket


内容长度已正确设置,客户端和服务器都支持分块编码。 - Randy

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