servlets - 我应该设置response.setContentLength() header 吗?

标签 servlets http-content-length

如果我在发送包含 zip 文件的 HttpServletResponse 时未指定 Content-Length header ,会发生什么情况?

我做了一些测试,似乎 header 默认设置为正确的文件长度。我能确定这种情况总是会发生吗?我什么时候可以找到一些相关文档?

最佳答案

如果实际响应内容长度完全适合响应缓冲区,通常为 2KB(取决于服务器 make/version/config),则将设置内容长度 header 。但是,如果实际响应内容长度大于响应缓冲区,因此会在到达响应内容末尾之前刷新它,则 servlet 将发送带有 chunked encoding 的响应。并忽略任何设置内容长度 header 的尝试。

HttpServlet#doGet() 的 javadoc 中提到了这一点引用如下:

...

Where possible, set the Content-Length header (with the ServletResponse.setContentLength(int) method), to allow the servlet container to use a persistent connection to return its response to the client, improving performance. The content length is automatically set if the entire response fits inside the response buffer.

When using HTTP 1.1 chunked encoding (which means that the response has a Transfer-Encoding header), do not set the Content-Length header.

...

使用“正常”编码,数据作为一个连续 block 发送。

actualContent

使用分块编码,数据以如下所示的 block 形式发送

part1LengthInHexadecimal
actualPart1Content

part2LengthInHexadecimal
actualPart2Content

part3LengthInHexadecimal
actualPart3Content

0

十六进制的部分长度指示客户端下一个数据 block 有多大(这样它就不会“意外地”将下一个数据 block 解析为当前数据 block 的一部分)。最后,客户将各个部件粘合在一起。顺便说一句,这也是在响应上使用 Gzip 时的默认行为,因为最终内容长度事先未知。

另请参阅 wikipedia 中的示例.

请注意,当省略文件下载的内容长度时,用户体验将是文件下载进度未知。 IE。最终用户不会看到任何有关文件大小和剩余字节/时间的指示。如果这种用户体验对您很重要,那么您应该提前设置内容长度。您可以通过首先写入内存缓冲区(例如 new ByteArrayOuputStream(bytes))或临时文件(例如 Files#createTempFile())来完成此操作,这样您就可以获得通过 bytes.lengthfile.length() 确定内容长度,然后最终将该临时缓冲区/文件写入响应。

关于servlets - 我应该设置response.setContentLength() header 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14381825/

相关文章:

java - Spring MVC 应用程序可以是多线程的,即使它的 servlet 不是吗?

c# - ASP.NET Web Api - 使用分块传输编码时,框架不会将 JSON 转换为对象

PHP file_get_contents() 遵循 Content-length header

java - JDBC 从 SQL 查询中解析 int

java - Tomcat 中存在的过滤器在 Jetty 中不存在,如何让 Jetty 忽略它?

spring - 了解 spring 调度程序 servlet 初始化

java - Servlet上下文和Spring应用上下文的本质区别

node.js - Axios 手动设置 Content-Length,nodeJS

node.js - 如何使用 fetch 使用 multipart/form-data header 和 FormData 进行 POST

PHP Content-Length header 不起作用