轉自來自點擊打開鏈接
接着上一篇,我們繼續來分析HttpURLConnection的使用,以及兩者的共同點和區別。
目錄
- 用法
- HttpURLConnection
- 區別
- 引用資料
用法
HttpURLConnection的用法
一、創建HttpURLConnection對象
URL url = new URL("http://localhost:8080/TestHttpURLConnectionPro/index.jsp"); URLConnection urlConnection = url.openConnection(); HttpURLConnection httpUrlConnection = (HttpURLConnection) urlConnection;
-
這個創建方法大家應該都很熟悉了,可能會認為下文中使用的HttpURLConnection的API的實現就在HttpURLConnection中了。這里要注意一下,其實這個HttpURLConnection是一個抽象類。
-
也就是說里面很多API函數都不在這兒實現的,那在哪實現呢。翻開java源碼,可以看到,URL.openConnection()的實現是在java.net.URL類中。
//java.net.URL類里面的openConnection方法: public URLConnection openConnection(Proxy proxy){ … return handler.openConnection(this, proxy); }
- 這里的handler又是什么呢,跟進去,發現Handler是sun.net.www.protocol.http.Handler這個java類,繼承java.net.URLStreamHandler類,是用來處理http連接請求響應的。 繼續跟蹤代碼
//Handler的方法 protected java.net.URLConnection openConnection(URL u, Proxy p) throws IOException { return new HttpURLConnection(u, p, this); }
-
二、HttpURLConnection參數設置最終發現只是簡單的生成了HttpURLConnection對象,其實最重要的HttpURLConnection就在這里了,這個是sun.net.www.protocl.http.HttpURLConnection類的對象,繼承java.net.HttpURLConnection。也就是說我們之后所用的API實現都在sun.net.www.protocl.http.HttpURLConnection這個類里面。所以大家想要看HttpURLConnection的源碼實現的話,需要到這個類中去查看。好了,說了這么多,下面還是介紹HttpURLConnection常用的API的使用吧。
1、設置是否向httpUrlConnection輸出,默認情況下是false。使用httpUrlConnection.getOutputStream(),把內容輸出到遠程服務器上。
httpUrlConnection.setDoOutput(true);
2、設置是否從httpUrlConnection讀入,默認情況下是true。使用httpUrlConnection.getInputStream(),從遠程服務器上得到響應的內容。
httpUrlConnection.setDoInput(true);
3、是否使用緩存。
httpUrlConnection.setUseCaches(false);
4、設定傳送的內容類型是可序列化的java對象 (如果不設此項,在傳送序列化對象時,當WEB服務默認的不是這種類型時可能拋java.io.EOFException)。
httpUrlConnection.setRequestProperty("Content-type", "application/x-java-serialized-object");
5、設定請求的方法為”POST”,默認是GET 。
httpUrlConnection.setRequestMethod("POST");
三、HttpURLConnection連接
|
|
四、HttpURLConnection寫數據與發送數據
// 現在通過輸出流對象構建對象輸出流對象,以實現輸出可序列化的對象。 ObjectOutputStream objOutputStrm = new ObjectOutputStream(outStrm); // 向對象輸出流寫出數據,這些數據將存到內存緩沖區中 objOutputStrm.writeObject(new String("我是測試數據")); // 刷新對象輸出流,將任何字節都寫入潛在的流中(些處為ObjectOutputStream) objOutputStm.flush(); // 關閉流對象。此時,不能再向對象輸出流寫入任何數據,先前寫入的數據存在於內存緩沖區中, // 在調用下邊的getInputStream()函數時才把准備好的http請求正式發送到服務器 objOutputStm.close(); // 調用HttpURLConnection連接對象的getInputStream()函數, // 將內存緩沖區中封裝好的完整的HTTP請求電文發送到服務端。 // <===注意,實際發送請求的代碼段就在這里 InputStream inStrm = httpConn.getInputStream();
五、HttpURLConnection注意事項
1. HttpURLConnection的connect()函數,實際上只是建立了一個與服務器的tcp連接,並沒有實際發送http請求。無論是post還是get請求,http請求實際上直到HttpURLConnection的getInputStream()這個函數里面才正式發送出去。所以對outputStream的寫操作,必須要在inputStream的讀操作之前。
2. 在用POST方式發送URL請求時,URL請求參數的設定順序是重中之重,對connection對象的一切配置(那一堆set函數)都必須要在connect()函數執行之前完成。
區別
-
功能用法對比
-
從功能上對比,HttpClient庫要豐富很多,提供了很多工具,封裝了http的請求頭,參數,內容體,響應,還有一些高級功能,代理、COOKIE、鑒權、壓縮、連接池的處理。
-
HttpClient高級功能代碼寫起來比較復雜,對開發人員的要求會高一些,而HttpURLConnection對大部分工作進行了包裝,屏蔽了不需要的細節,適合開發人員直接調用。
-
另外,HttpURLConnection在2.3版本增加了一些HTTPS方面的改進,4.0版本增加一些響應的緩存。
-
-
性能對比
-
HttpUrlConnection直接支持GZIP壓縮;HttpClient也支持,但要自己寫代碼處理。
-
HttpUrlConnection直接支持系統級連接池,即打開的連接不會直接關閉,在一段時間內所有程序可共用;HttpClient當然也能做到,但畢竟不如官方直接系統底層支持好。
-
HttpUrlConnection直接在系統層面做了緩存策略處理(4.0版本以上),加快了重復請求的速度。
-
這篇文章對兩者的速度做了一個對比,做法是兩個類都使用默認的方法去請求百度的網頁內容,測試結果是使用httpurlconnection耗時47ms,使用httpclient耗時641ms。httpURLConnection在速度有比較明顯的優勢,當然這跟壓縮內容和緩存都有直接關系。
-
-
未來發展
-
HttpClient 適用於 web browsers, 他們是可擴展的,並且擁有大量的穩定APIs。但是,在不破壞其兼容性的前提下很難對如此多的APIs做修改。因此,Android 團隊對修改優化Apache HTTP Client表現的並不積極。
-
HttpURLConnect 是一個通用的、適合大多數應用的輕量級組件。這個類起步比較晚,很容易在主要API上做穩步的改善。但是HttpURLConnection在在Android 2.2及以下版本上存在一些令人厭煩的bug,尤其是在讀取 InputStream時調用 close()方法,就有可能會導致連接池失效了。
-
Android團隊未來的工作會將更多的時間放在優化HttpURLConnection上,它的API簡單,體積較小,因而非常適用於Android項目。壓縮和緩存機制可以有效地減少網絡訪問的流量,在提升速度和省電方面也起到了較大的作用。
-
-
選用建議
-
如果一個Android應用需要向指定頁面發送請求,但該頁面並不是一個簡單的頁面,只有當用戶已經登錄,而且登錄用戶的用戶名有效時才可訪問該頁面。如果使用HttpURLConnection來訪問這個被保護的頁面,那么需要處理的細節就太復雜了。這種情況建議使用HttpClient。
-
Android2.3及以上版本建議選用HttpURLConnection,2.2及以下版本建議選用HttpClient。新的應用都建議使用HttpURLConnection。
-