歡迎轉帖,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的時候的一種需要考慮的情況,本人沒有驗證過。