HttpClient和HttpURLConnection的使用和区别(上)
轉(zhuǎn)自:點擊打開鏈接
相信很多Android開發(fā)者碰到涉及到Http協(xié)議的需求時,都和我一樣在猶豫是使用HttpClient還是使用HttpURLConnection呢。我在網(wǎng)上也搜索了很多文章,來分析兩者的區(qū)別。接下來我們就剖析一下這兩個網(wǎng)絡(luò)開源庫,分別從背景、用法、相同點、區(qū)別這幾點來入手分析。
目錄
- 補(bǔ)充知識
- 背景
- 用法
- HttpClient
補(bǔ)充知識
-
TCP/IP、Socket、HTTP簡要介紹
-
TCP/IP中文名為傳輸控制協(xié)議/因特網(wǎng)互聯(lián)協(xié)議,又名網(wǎng)絡(luò)通訊協(xié)議,是Internet最基本的協(xié)議、Internet國際互聯(lián)網(wǎng)絡(luò)的基礎(chǔ),由網(wǎng)絡(luò)層的IP協(xié)議和傳輸層的TCP協(xié)議組成。
-
Socket是支持TCP/IP協(xié)議的網(wǎng)絡(luò)通信基本操作單元,許多操作系統(tǒng)為應(yīng)用程序提供了一套調(diào)用接口(API),方便開發(fā)者開發(fā)網(wǎng)絡(luò)程序。注意,socket本身并不是協(xié)議,只是提供一個針對TCP或UDP的編程接口。
-
HTTP協(xié)議是一個web服務(wù)器和客戶端通信的超文本傳送協(xié)議,是建立在TCP協(xié)議上的一個應(yīng)用層協(xié)議。
HTTP連接最顯著的特點是客戶端發(fā)送的每次請求都需要服務(wù)器回送響應(yīng),在請求結(jié)束后,會主動釋放連接。從建立連接到關(guān)閉連接的過程稱為“一次連接”。 -
HTTP1.0
客戶端的每次請求都要求建立一次單獨的連接,在處理完本次請求后,就自動釋放連接。 -
HTTP1.1
可以在一次連接中處理多個請求,并且多個請求可以重疊進(jìn)行,不需要等待一個請求結(jié)束后再發(fā)送下一個請求。
背景
-
HttpClient
Apache公司提供的庫,提供高效的、最新的、功能豐富的支持HTTP協(xié)議工具包,支持HTTP協(xié)議最新的版本和建議,是個很不錯的開源框架,封裝了http的請求,參數(shù),內(nèi)容體,響應(yīng)等,擁有眾多API。
-
HttpURLConnection
Sun公司提供的庫,也是Java的標(biāo)準(zhǔn)類庫java.net中的一員,但這個類什么都沒封裝,用起來很原始,若需要高級功能,則會顯得不太方便,比如重訪問的自定義,會話和cookie等一些高級功能。
用法
這兩種方式都支持HTTPS協(xié)議,以流的形式進(jìn)行上傳和下載,配置超時時間,IPV6,連接池等功能。
HttpClient的用法
一、執(zhí)行請求
HttpClient最重要的功能是執(zhí)行HTTP方法。一個HTTP方法的執(zhí)行包含一個或多個HTTP請求/HTTP響應(yīng)交流,通常由HttpClient的內(nèi)部來處理。用戶提供一個請求對象,HttpClient發(fā)送請求到目標(biāo)服務(wù)器,希望服務(wù)器返回一個相應(yīng)的響應(yīng)對象,或者拋出一個異常(執(zhí)行失敗)。
一個簡單的請求執(zhí)行過程的示例:
HttpClient httpclient = new DefaultHttpClient(); HttpGet httpget = new HttpGet("http://localhost/"); HttpResponse response = httpclient.execute(httpget); HttpEntity entity = response.getEntity(); if (entity != null) {InputStream instream = entity.getContent();int l;byte[] tmp = new byte[2048];while ((l = instream.read(tmp)) != -1) {} }二、用工具封裝Get請求
對比下面兩段代碼,發(fā)現(xiàn)用httpClient提供的方法更具可讀性
HttpGet httpget = new HttpGet( "http://www.google.com/search?hl=en&q=httpclient&btnG=Google+Search&aq=f&oq=");HttpClient提供很多工具方法來簡化創(chuàng)建和修改執(zhí)行URI,例如:
List<NameValuePair> qparams = new ArrayList<NameValuePair>(); qparams.add(new BasicNameValuePair("q", "httpclient")); qparams.add(new BasicNameValuePair("btnG", "Google Search")); qparams.add(new BasicNameValuePair("aq", "f")); qparams.add(new BasicNameValuePair("oq", null)); URI uri = URIUtils.createURI("http", "www.google.com", -1, "/search", URLEncodedUtils.format(qparams, "UTF-8"), null); HttpGet httpget = new HttpGet(uri);三、處理頭部消息
一個HTTP消息可以包含一系列頭部描述消息的屬性。例如:內(nèi)容長度、內(nèi)容類型等。
HttpClient提供方法檢索、添加、刪除、枚舉頭部信息。
HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1,HttpStatus.SC_OK, "OK"); response.addHeader("Set-Cookie","c1=a; path=/; domain=localhost"); response.addHeader("Set-Cookie","c2=b; path=/; domain=localhost"); //獲取header的方法1 Header h1 = response.getFirstHeader("Set-Cookie"); Header h2 = response.getLastHeader("Set-Cookie"); //獲取header的方法2 HeaderIterator it = response.headerIterator("Set-Cookie"); while (it.hasNext()) {System.out.println(it.next()); } //獲取header的方法3 Header[] headers = response.getAllHeaders(); for (Header header : headers) {System.out.println(header.getName() + " | " + header.getValue()); }四、HTTP實體
HTTP規(guī)范定義了兩種包裝實體的方法:POST和PUT。響應(yīng)通常附上內(nèi)容實體。
HttpClient根據(jù)其內(nèi)容出自何處區(qū)分三種類型的實體:
streamed(流式):內(nèi)容從流中獲得,或者在運行中產(chǎn)生。流式實體是不可重復(fù)生成的。
self-contained(自我包裝式):內(nèi)容在內(nèi)存中或通過獨立的連接或其它實體中獲得。自我包裝式的實體是可以重復(fù)生成和讀取的。經(jīng)常用于封裝HTTP請求實體。(像ByteArrayEntity或StringEntity)。
wrapping(包裹式):內(nèi)容從另外一個實體中獲得。
如果從一個HTTP響應(yīng)中獲取流式內(nèi)容,這個區(qū)別對于連接管理很重要。
如果是應(yīng)用程序創(chuàng)建并用于發(fā)送的請求實體,這個類型區(qū)別就沒那么重要了。
五、使用HTTP實體
使用實體常用的一些API,得到內(nèi)容類型、內(nèi)容長度、內(nèi)容編碼、內(nèi)容轉(zhuǎn)換成String或ByteArray、設(shè)置分塊(HTTP1.1)。但是,EntityUtils的使用是不鼓勵的,除非實體響應(yīng)來自一個可信賴的HTTP服務(wù)器和已知的有限長度。
myEntity.getContentType() myEntity.getContentLength() EntityUtils.getContentCharSet(myEntity) EntityUtils.toString(myEntity) EntityUtils.toByteArray(myEntity) myEntity.setChunked(true);六、得到實體內(nèi)容
HttpGet httpget = new HttpGet("http://localhost/"); HttpResponse response = httpclient.execute(httpget); HttpEntity entity = response.getEntity(); if (entity != null) {long len = entity.getContentLength();if (len != -1 && len < 2048) {System.out.println(EntityUtils.toString(entity));} else {InputStream instream = entity.getContent();int byteOne = instream.read();int byteTwo = instream.read();//終止請求,該連接將不被重用,保證底層的資源被正確釋放httpget.abort();} }
七、生成實體內(nèi)容
HttpClient提供了常見的數(shù)據(jù)容器,比如字符串,字節(jié)數(shù)組,輸入流和文件:StringEntity,ByteArrayEntity,InputStreamEntity和FileEntity。
File file = new File("somefile.txt"); FileEntity entity = new FileEntity(file, "text/plain; charset=\"UTF-8\""); HttpPost httppost = new HttpPost("http://localhost/action.do"); httppost.setEntity(entity);
八、HTML表單(UrlEncodedFormEntity)
許多應(yīng)用程序需要頻繁模擬提交一個HTML表單的過程,比如,為了來記錄一個Web應(yīng)用程序或提交輸出數(shù)據(jù)。HttpClient提供了特殊的實體類UrlEncodedFormEntity來這個滿足過程。
九、響應(yīng)處理器(ResponseHandler)
ResponseHandler能夠保證在任何情況下都會將底層的HTTP連接釋放回連接管理器。用戶不必?fù)?dān)心HttpClient連接占用系統(tǒng)資源,可以把注意力集中在處理HTTP響應(yīng)內(nèi)容。
HttpClient還提供了很多高級的特性,如:連接管理、狀態(tài)管理、認(rèn)證管理、客戶服務(wù)等。這里只介紹了一些基礎(chǔ)的用法,有時間好好研究一下,再專門寫一篇關(guān)于HttpClient的博客。
轉(zhuǎn)載于:https://www.cnblogs.com/liushuibufu/p/4140914.html
總結(jié)
以上是生活随笔為你收集整理的HttpClient和HttpURLConnection的使用和区别(上)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HTML之列表学习-9.23
- 下一篇: 图解面向对象中的聚合与耦合概念