Tomcat 中響應頭信息(Http Response Header) Content-Length 和 Transfer-Encoding 之種種

歡迎轉帖,But請註明出處謝謝: http://blog.csdn.net/shootyou/archive/2011/01/13/6135669.aspx

 

 

先說說原理:

 

客戶端(PC瀏覽器或者手機瀏覽器)在接受到Tomcat的響應的時候,頭信息通常都會帶上Content-Length ,一般情況下客戶端會在接受完Content-Length長度的數據之後纔會開始解析。而在Tomcat上,頁面處理過程中會將需要out.print的數據都放在緩存中,然後一次性的返回給客戶端。

 

另外一種情況就是頭信息中不存在Content-Length ,取而代之的是Tansfer-Encoding:chunked ,這個頭信息的的意思是response的內容會被Tomcat分成一塊一塊的發送,客戶端也就不需要等到內容都傳輸完畢了才解析其中的內容。因爲這個時候被傳送的數據長度是無法預計的,所以存在Tansfer-Encoding:chunked的話也沒有存在Content-Length 的意義了。

那麼問題來了,具體在應用的時候如何控制Tomcat響應的是Content-Length還是Tansfer-Encoding呢?

我們都知道內置對象out,在調用print或者write的時候都會先往內部buffer裏頭寫數據,而不是直接輸出到客戶端。Response Header 的 Content-Length 其實就是計算了buffer的數據長度。那他什麼時候輸出到客戶端呢?有幾種情況:

1. out的屬性autoFlush爲true,那麼當buffer(默認大小是8 * 1024)的數據滿了,Tomcat會自動向客戶端flush一次數據,之後buffer就被重置了。必然Content-Length就拿不到了。所以這個時候Repsonse Header就成了Tansfer-Encoding:chunked。

2. out的屬性autoFlush爲false,如果數據超出了buffer的容量,這個時候會拋出異常IOException。

3. 如果數據在buffer的容量範圍之內,那麼Content-Length可以被計算,頭信息就會帶上Content-Length。

4. 如果手動調用了out.flush(),那麼buffer中的數據立即會被輸出到客戶端,這個時候響應數據其實還未傳輸完畢,所以這種傳輸也可以看做分塊傳輸了。Repsonse Header自然是Tansfer-Encoding:chunked。

從以上幾種情況可以看出,一旦調用了out.flush,buffer就被重置了,Content-Length就無法計算了,Repsonse Header必然是Tansfer-Encoding:chunked。

另外如果有需要自己編寫客戶端的,可以參考下:http://hfutxf.javaeye.com/blog/807647 ,裏面會說到Tansfer-Encoding:chunked的時候的一種需要考慮的情況,本人沒有驗證過。

發佈了56 篇原創文章 · 獲贊 37 · 訪問量 92萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章