【发布时间】:2019-08-30 19:12:24
【问题描述】:
我遇到了一个返回大约 900k XML 的端点。时不时地(在今天的测试中不到 5000 分之一)我得到一个 MalformedChunkCodingException
这是在 Spring 3 上构建的相当老的 webapp(约 10 年)中发生的。我转而直接使用 RestTemplate 而不是 httpclient,但这并没有解决它。今天在 httpclient 上启用了线级日志记录运行了几个小时后,我设法捕获了一个。
Caused by: org.apache.http.MalformedChunkCodingException: Unexpected content at the end of chunk
at org.apache.http.impl.io.ChunkedInputStream.getChunkSize(ChunkedInputStream.java:259)
at org.apache.http.impl.io.ChunkedInputStream.nextChunk(ChunkedInputStream.java:227)
at org.apache.http.impl.io.ChunkedInputStream.read(ChunkedInputStream.java:186)
at org.apache.http.conn.EofSensorInputStream.read(EofSensorInputStream.java:137)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.Reader.read(Reader.java:140)
at org.springframework.util.StreamUtils.copyToString(StreamUtils.java:74)
at org.springframework.http.converter.StringHttpMessageConverter.readInternal(StringHttpMessageConverter.java:85)
at org.springframework.http.converter.StringHttpMessageConverter.readInternal(StringHttpMessageConverter.java:40)
at org.springframework.http.converter.AbstractHttpMessageConverter.read(AbstractHttpMessageConverter.java:153)
at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:103)
at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:724)
at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:709)
通常日志看起来是这样的:
DEBUG org.apache.http.wire - << "words words words"
DEBUG org.apache.http.wire - << "[\r][\n]"
DEBUG org.apache.http.wire - << "FAF[\r][\n]"
DEBUG org.apache.http.wire - << "words words words up to FAF bytes"
DEBUG org.apache.http.wire - << "[\r][\n]"
DEBUG org.apache.http.wire - << "BAA[\r][\n]"
DEBUG org.apache.http.wire - << "words words words up to BAA bytes"
但在出错的那一个中,我有这个:
DEBUG org.apache.http.wire - << "words words words"
DEBUG org.apache.http.wire - << "[\r][\n]"
DEBUG org.apache.http.wire - << "B50[\r][\n]"
DEBUG org.apache.http.wire - << "words words words up to B50 bytes"
DEBUG org.apache.http.wire - << "3FC0[\r][\n]"
它缺少 B50 块末尾的 [\r][\n]。
所以,假设我可以信任 org.apache.http.wire 调试,那么我的应用程序正在接收这样的流,而且它的格式不正确。它们之间的 haproxy 是否有可能破坏了流?
幸运与否,对话的另一端也是我的应用程序之一,在 Spring 4.2.4 的 tomcat 中运行。
我从哪里开始寻找谁在构建无效响应?春天?雄猫?
看起来我可以禁用分块,但我只是在构建响应时计算我的内容长度,我并不热衷于这样做,因为那样我将不得不手动序列化我的响应,而不是让 Spring去做吧。
【问题讨论】:
标签: java spring http tomcat chunked-encoding