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()的時候才是去讀取數據的時候,過早的關閉均會導致獲取不到數據