httpclient在获取response的entity时报异常

Posted kumu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了httpclient在获取response的entity时报异常相关的知识,希望对你有一定的参考价值。

httpClient报异常:Premature end of chunk coded message body: closing chunk expected

技术分享图片

首先这个异常提示直译过来就是:被编码信息体数据块的过早结尾,数据块关闭异常

昨天第一眼看到这个异常时,我是丈二和尚摸不着头脑,一通搜索也没搞清楚。当时时间较晚就先睡觉了,然后今天再测试时还是这个异常,这个时候我就仔细看了下这个异常提示,关键词是“Premature(过早)”和“end(结束)”,那么按照这个提示思路我就发现我出错的原因是过早关闭了HttpResponse这个对象了。所以这个bug的教训就是要仔细阅读理解异常的提示内容。好了,接下来是按照我自己的实际代码来分析。

 

 

最开始我是这么处理的,首先是执行GET请求,获取到response之后二次封装成自定义的HttpResponseEntity(提取状态码和Entity),然后return后续再处理。

看下面一张图的代码可知,我在finally里面进行了response.close()释放资源。

技术分享图片

 

然后在下图里的后续处理中使用EntityUtils.toString()来获取Entity中的数据。

从实际的异常堆栈提示可知,实际抛异常的地方就是红框所框选的位置,也就是EntityUtils.toString()。

技术分享图片

 

至于为什么使用EntityUtils.toString()会导致异常呢?难道数据不是已经被请求到,并保存在Entity之中的了嘛?

答案是:数据还没真正被获取到,具体可以看EntityUtils.toString()的源码,如下图。

在toString()的开头便获取了InputStream输入流,然后读取数据后在最后面instream.close()关闭输入流(图太长,只截取头尾两部分),个人觉得这里的输入流是与socket相关的流。

也就是说toString()的时候才是去读取数据的时候,过早的关闭均会导致获取不到数据

技术分享图片

技术分享图片

 

以上是关于httpclient在获取response的entity时报异常的主要内容,如果未能解决你的问题,请参考以下文章

httpclient请求啥状况200状态下返回的response的数据为空

如何在 HttpClient 的请求中添加、设置和获取 Header?

httpclient问题求大神,executeMethod如何么到response? httpClient.executeMethod(get);

Angular 6 和 Spring boot - 无法使用简单的 HttpClient 调用获取数据

获取相应头信息Response Headers的内容类型Content-Type

是否支持将基于 OAuth2 的 Bearer 令牌与 Apache HttpClient 一起使用?