在與第三方合作的過程中,響應報文是xml格式的。最開始沒有進行處理,對方收到的報文是chunked模式。對方說目前不支援這個模式,於是我就去尋找了什麼叫chunked模式,以及怎麼去避免使用這種模式。
簡單介紹一下chunked:
Transfer-Encoding: chunked 表示輸出的內容長度不能確定,普通的靜態頁面、圖片之類的基本上都用不到這個。
但動態網頁面就有可能會用到,但我也注意到大部分asp,php,asp.net動態網頁面輸出的時候大部分還是使用Content-Length,沒有使用Transfer-Encoding: chunked。
不過如果結合:Content-Encoding: gzip 使用的時候,Transfer-Encoding: chunked還是比較有用的。
記得以前實現:Content-Encoding: gzip 輸出時,先把整個壓縮後的資料寫到一個很大的位元組數組裡(如 ByteArrayOutputStream),然後得到數組大小 -> Content-Length。
如果結合Transfer-Encoding: chunked使用,就不必申請一個很大的位元組數組了,可以一塊一塊的輸出,更科學,佔用資源更少。
這在http協議中也是個常見的欄位,用於http傳送過程的分塊技術,原因是http伺服器響應的報文長度經常是不可預測的,使用Content-length的實體搜捕並不是總是管用。
分塊技術的意思是說,實體被分成許多的塊,也就是應用程式層的資料,TCP在傳送的過程中,不對它們做任何的解釋,而是把應用程式層產生資料全部理解成二進位流,然後按照MSS的長度切成一分一分的,一股腦塞到tcp協議棧裡面去,而具體這些二進位的資料如何做解釋,需要應用程式層來完成,所以在這之前,一快整體應用程式層的資料需要等它分成的所有TCP segment到達對方,重新組裝後,應用程式才使用自己的解碼方法還原它們。
HTTP1.1採用了持久的串連,也就是一次TCP的串連不馬上釋放,允許許多的請求跟響應在一個TCP的串連上發送,所以客戶機與伺服器需要某種方式來標示一個報文在哪裡結束和在下一個報文在哪裡開始。簡單的方法是使用呢content-length,但這隻有當報文長度可以預先判斷的時候才起作用,而對於動態內容或者在發送資料前不能判定長度的情況下,可以使用分塊的方法來傳送編碼。
Web伺服器有時產生HTTPResponse無法在Header就確定訊息大小的,這時一般來說伺服器將不會提供Content-Length的頭資訊,而採用Chunked編碼動態提供body內容的長度。進行Chunked編碼傳輸的HTTP Response會在訊息頭部設定:Transfer-Encoding: chunked,表示Content Body將用Chunked編碼傳輸內容。
簡而言之:在httpresponse傳輸過程中,不知道要傳輸的內容的具體大小,所以就採用chunked(分塊)模式,這樣,有點類似於流媒體的趕腳。一段一段的傳輸。
那麼,根據這個含義,想要去掉chunked模式,我們只需要把要傳輸的內容的大小告訴httpresponse即可了,就是:
response.setContentLength(1000);
response.setContentType("text/html;charset=UTF-8");// 解決中文亂碼
response.setCharacterEncoding("UTF-8");//設定字元集編碼
response.setContentLength(rspString.length());//設定傳輸內容大小(注意:要在printWriter = response.getWriter();之前)
//以下是將內容進行傳輸了
printWriter = response.getWriter();
printWriter.print(rspString);
printWriter.flush();
printWriter.close();