Jetty 12搭配Spring 6时响应缺失Content-Length的问题问询
问题分析:Jetty搭配Spring时Connection:close请求下响应缺失Content-Length/Transfer-Encoding头的原因
现象回顾
当客户端发送带有Connection:close请求头的请求时:
- 普通Servlet的响应会正常返回
Content-Length头(如示例中的Content-Length: 2),符合RFC2616第4.4节要求(响应必须包含Content-Length或Transfer-Encoding:chunked二者之一)。 - 但使用
HttpMessageConverter(如GsonHttpMessageConverter)的Spring控制器响应,既没有Content-Length也没有Transfer-Encoding:chunked头,仅返回Connection: close,违反HTTP规范。 - 该问题在Jetty 9/11/12搭配Spring 4/5/6的组合中均存在。
核心原因解析
1. Spring HttpMessageConverter的流式输出逻辑
Spring的HttpMessageConverter默认采用流式写入响应体的方式:它直接将序列化后的内容逐步写入响应输出流,不会先把整个响应内容序列化到内存中计算长度,因此不会主动设置Content-Length头。
而普通Servlet示例中,开发者可能提前完成了内容序列化并手动设置了Content-Length,或者Servlet容器在处理小体积输出时自动完成了长度计算,所以能正常返回该头。
2. Jetty针对Connection:close场景的特殊处理
Jetty在检测到请求头包含Connection:close时,会触发连接关闭的逻辑:它认为客户端会通过连接的关闭来判断响应的结束,因此跳过了Transfer-Encoding:chunked头的设置。但这一逻辑忽略了RFC2616第4.4节的强制要求,导致响应头不符合规范。
3. 跨版本的交互遗留问题
从Jetty 9到12、Spring 4到6的版本组合中都存在该问题,说明这是两者交互逻辑中的长期遗留问题:Spring不主动提供响应长度信息,Jetty在Connection:close场景下不自动补充分块编码头,最终导致响应头缺失必要字段。
内容的提问来源于stack exchange,提问作者jd_abc
相关产品推荐
相关产品推荐

