5.1 HttpClient門面
HttpClient接口代表了最重要的HTTP請求執行的契約。它沒有在請求執行處理上強加限制或特殊細節,而在連接管理,狀態管理,認證和處理重定向到具體實現上留下了細節。這應該使得很容易使用額外的功能,比如響應內容緩存來裝飾接口。
DefaultHttpClient是HttpClient接口的默認實現。這個類扮演了很多特殊用戶程序或策略接口實現負責處理特定HTTP協議方面,比如重定向到處理認證或做出關于連接持久化和保持活動的持續時間決定的門面。這使得用戶可以選擇使用定制,具體程序等來替換某些方面默認實現。
DefaultHttpClient httpclient = new DefaultHttpClient();httpclient.setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy() {@Overridepublic long getKeepAliveDuration(HttpResponse response,HttpContext context) {long keepAlive = super.getKeepAliveDuration(response, context);if (keepAlive == -1) {// 如果keep-alive值沒有由服務器明確設置,那么保持連接持續5秒。keepAlive = 5000;}return keepAlive;}});
DefaultHttpClient也維護一組協議攔截器,意在處理即將離開的請求和即將到達的響應,而且提供管理那些攔截器的方法。新的協議攔截器可以被引入到協議處理器鏈中,或在需要時從中移除。內部的協議攔截器存儲在一個簡單的java.util.ArrayList中。它們以被加入到list中的自然順序來執行。
DefaultHttpClient httpclient = new DefaultHttpClient();httpclient.removeRequestInterceptorByClass(RequestUserAgent.class);httpclient.addRequestInterceptor(new HttpRequestInterceptor() {public void process(HttpRequest request, HttpContext context)throws HttpException, IOException {request.setHeader(HTTP.USER_AGENT, "My-own-client");}});
DefaultHttpClient是線程安全的。建議相同的這個類的實例被重用于多個請求的執行。當一個DefaultHttpClient實例不再需要而且要脫離范圍時,和它關聯的連接管理器必須調用ClientConnectionManager#shutdown()方法關閉。
HttpClient httpclient = new DefaultHttpClient();// 做些有用的事httpclient.getConnectionManager().shutdown();
5.2 HttpClient參數
- 'http.protocol.handle-redirects':定義了重定向是否應該自動處理。這個參數期望得到一個java.lang.Boolean類型的值。如果這個參數沒有被設置,HttpClient將會自動處理重定向。
- 'http.protocol.reject-relative-redirect':定義了是否相對的重定向應該被拒絕。HTTP規范需要位置值是一個絕對URI。這個參數期望得到一個java.lang.Boolean類型的值。如果這個參數沒有被設置,那么就允許相對重定向。
- 'http.protocol.max-redirects':定義了要遵循重定向的最大數量。這個重定向數字的限制意在防止由破碎的服務器端腳本引發的死循環。這個參數期望得到一個java.lang.Integer類型的值。如果這個參數沒有被設置,那么只允許不多余100次重定向。
- 'http.protocol.allow-circular-redirects':定義環形重定向(重定向到相同路徑)是否被允許。HTTP規范在環形重定向沒有足夠清晰的允許表述,因此這作為可選的是可以開啟的。這個參數期望得到一個java.lang.Boolean類型的值。如果這個參數沒有被設置,那么環形重定向就不允許。
- 'http.connection-manager.factory-class-name':定義了默認的ClientConnectionManager實現的類型。這個參數期望得到一個java.lang.String類型的值。如果這個參數沒有被設置,對于每個默認的將使用SingleClientConnManager。
- 'http.virtual-host':定義了在頭部信息Host中使用的虛擬主機名稱,來代替物理主機名稱。這個參數期望得到一個HttpHost類型的值。如果這個參數沒有被設置,那么將會使用目標主機的名稱或IP地址。
- 'http.default-headers':定義了每次請求默認發送的頭部信息。這個參數期望得到一個包含Header對象的java.util.Collection類型值。
- 'http.default-host':定義了默認主機。如果目標主機沒有在請求URI(相對URI)中明確指定,那么就使用默認值。這個參數期望得到一個HttpHost類型的值。
5.3 自動重定向處理
HttpClient處理所有類型的自動重定向,除了那些由HTTP規范明令禁止的,比如需要用戶干預的。參考其它(狀態碼303)POST和PUT請求重定向轉換為由HTTP規范需要的GET請求。
5.4 HTTP客戶端和執行上下文
DefaultHttpClient將HTTP請求視為不變的對象,也從來不會假定在請求執行期間改變。相反,它創建了一個原請求對象私有的可變副本,副本的屬性可以基于執行上下文來更新。因此,如目標主鍵和請求URI的final類型的請求參數可以在請求執行之后,由檢查本地HTTP上下文來決定。
DefaultHttpClient httpclient = new DefaultHttpClient();HttpContext localContext = new BasicHttpContext();HttpGet httpget = new HttpGet("http://localhost:8080/");HttpResponse response = httpclient.execute(httpget, localContext);HttpHost target = (HttpHost) localContext.getAttribute(ExecutionContext.HTTP_TARGET_HOST);HttpUriRequest req = (HttpUriRequest) localContext.getAttribute(ExecutionContext.HTTP_REQUEST);System.out.println("Target host: " + target);System.out.println("Final request URI: " + req.getURI());System.out.println("Final request method: " + req.getMethod());