問題描述:
用 Hessian 實現 web service 過程中,需要建立對象時,是使用 HTTP POST 方法來傳遞資料的。但是在有反向 Proxy (nginx) 的情況下,會拋出異常 (com.caucho.hessian.client.HessianConnectionException: 411:java.io.IOException: Server returned HTTP response code: 411 for URL:http://xxxx/xxx/xxxService) 。
首先來看下 HTTP 411 錯誤的解釋: Length Required 伺服器不能處理請求,除非客戶發送一個 Content-Length 頭。( HTTP 1.1 新)這是因為 Hessian 與服務端通訊預設是採取分塊的方式 (chunked encoding) 發送資料,而反向 Proxy要獲得 Content-Length 這個頭,才能處理請求,但是 Hessian 的請求中並沒有加入這個參數。
解決方案:
com.caucho.hessian.client.HessianProxyFactory 類中,有一個 boolean _chunckedPost 的域成員,其預設值為 true 。這個值就是規定 Hessian 是否以分塊發送的方式與服務端交換資料的參數,因此在建立com.caucho.hessian.client.HessianProxyFactory 的對象後(假設為 factory ),只要調用其上的setChunckedPost() 方法,把這個屬性設定為 false 即可。即 factory.setChunkedPost(false);
分塊編碼傳輸:
分塊編碼 (chunked encoding) 傳輸方式是 HTTP 1.1 協議中定義的 Web 使用者向伺服器提交資料的一種方法,當伺服器收到 chunked 編碼方式的資料時會分配一個緩衝區存放之,如果提交的資料大小未知,用戶端會以一個協商好的分塊大小向伺服器提交資料。
The content can be broken up into a number of chunks; each of which is prefixed by its size in bytes. A zero size chunk indicates the end of the response message. If a server is using chunked encoding it must set the Transfer-Encoding header to "chunked".
Chunked encoding is useful when a large amount of data is being returned to the client and the total size of the response may not be known until the request has been fully processed. An example of this is generating an HTML table of results from a database query. If you wanted to use the Content-Length header you would have to buffer the whole result set before calculating the total content size. However, with chunked encoding you could just write the data one row at a time and write a zero sized chunk when the end of the query was reached.
如果不使用 Chunked encoding 傳輸方式,需要將要發送的資料緩衝下來,計算出 content-length ,從而滿足反向 Proxy( Nginx )需要 content-length 的要求。