Android 網(wǎng)絡(luò)編程(三)HttpURLConnection

HttpURLConnection
HTTP的URLConnection(RFC 2616)用于通過(guò)Web發(fā)送和接收數(shù)據(jù)眯杏。數(shù)據(jù)可以是任何類型和長(zhǎng)度。該類可用于發(fā)送和接收長(zhǎng)度未預(yù)先知道的流數(shù)據(jù)捞稿。


使用步驟

HttpURLConnection使用步驟:

  1. 通過(guò)調(diào)用URL.openConnection()獲取新的HttpURLConnection并將結(jié)果轉(zhuǎn)換為HttpURLConnection。
  2. 準(zhǔn)備請(qǐng)求
    請(qǐng)求的主要屬性是其URI钝尸。請(qǐng)求標(biāo)頭還可以包括諸如證書括享,content types和session cookies。
  3. 可選地上傳請(qǐng)求正文珍促。如果它們包含請(qǐng)求體,必須使用setDoOutput(true)來(lái)配置實(shí)例铃辖。通過(guò)寫入getOutputStream()返回的流來(lái)發(fā)送數(shù)據(jù)。
  4. 讀響應(yīng)猪叙。
    響應(yīng)頭通常包括元數(shù)據(jù)娇斩,如響應(yīng)主體的內(nèi)容類型和長(zhǎng)度,修改的日期和會(huì)話cookie穴翩。響應(yīng)主體可以從getInputStream()返回的流中讀取犬第。如果響應(yīng)沒(méi)有body,那么該方法返回一個(gè)空的流芒帕。
  5. 斷開(kāi)歉嗓。
    一旦響應(yīng)正文被讀取,HttpURLConnection應(yīng)該通過(guò)調(diào)用disconnect()關(guān)閉背蟆。斷開(kāi)連接釋放連接所持有的資源鉴分,以使其可能被關(guān)閉或重新使用。

Get請(qǐng)求

public static String getTask(String path){
    try {
        URL url = new URL(path);
        HttpURLConnection conn = (HttpURLConnection)url.openConnection();           
        conn.setRequestMethod("GET");  //設(shè)置請(qǐng)求方式
        conn.setConnectTimeout(5*1000); //設(shè)置連接超時(shí)時(shí)間
        conn.setRequestProperty("Connection", "Keep-Alive");
        InputStream in = conn.getInputStream();
        //BufferedInputStream帶有緩沖區(qū)的輸入流
        BufferedInputStream bis = new BufferedInputStream(in);
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        byte[]array = new byte[1024];
        int len =0;
        //讀取數(shù)據(jù)
        while((len = bis.read(array)) != -1){
            bos.write(array, 0, len);
        }
        bis.close();
        bos.close();
        conn.disconnect();  //斷開(kāi)連接
        String result = bos.toString("utf-8");
        Log.i(TAG, result);
        return result;
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}

打印

08-25 00:12:27.254: I/MainActivity(1140): <!DOCTYPE html>
08-25 00:12:27.254: I/MainActivity(1140): <html>
08-25 00:12:27.254: I/MainActivity(1140):     <!--STATUS OK-->
08-25 00:12:27.254: I/MainActivity(1140):     <head>
08-25 00:12:27.254: I/MainActivity(1140):         <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
08-25 00:12:27.254: I/MainActivity(1140):         <title>百度一下,你就知道</title>
08-25 00:12:27.254: I/MainActivity(1140):         <meta http-equiv="Cache-control" content="no-cache">
//.....

setRequestMethod函數(shù)參數(shù)為String類型,必須為以下幾種:OPTIONS、GET释液、HEAD、POST坏瘩、PUT、DELETE恭应、TRACE沧烈,必須是大寫敛纲。
HttpURLConnection默認(rèn)情況下使用GET請(qǐng)求喂击。如果setDoOutput(true)已經(jīng)被調(diào)用,它將使用POST载慈。其他HTTP方法(OPTIONS惭等,HEAD珍手,PUT办铡,DELETE和TRACE)可以使用setRequestMethod(String)設(shè)置。


Post請(qǐng)求

代碼如下:

public static String postTask(String path,String post){
    URL url = null;
    try {
        url = new URL(path);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("POST"); // 提交模式
        conn.setConnectTimeout(10000);//連接超時(shí) 單位毫秒
        conn.setReadTimeout(2000);//讀取超時(shí) 單位毫秒
        conn.setDoOutput(true);  // 發(fā)送POST請(qǐng)求必須設(shè)置為true
        conn.setDoInput(true);   //默認(rèn)為true琳要。
        conn.setFixedLengthStreamingMode(post.length());
        // 獲取URLConnection對(duì)象對(duì)應(yīng)的輸出流
        PrintWriter printWriter = new PrintWriter(conn.getOutputStream());
        // 發(fā)送請(qǐng)求參數(shù)
        printWriter.write(post);  //post的參數(shù) x=x&y=y
        // flush輸出流的緩沖
        printWriter.flush();
        //開(kāi)始獲取數(shù)據(jù)
        BufferedInputStream bis = new BufferedInputStream(conn.getInputStream());
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        int len;
        byte[] arr = new byte[1024];
        while((len=bis.read(arr))!= -1){
            bos.write(arr,0,len);
            bos.flush();
        }
        bis.close();
        bos.close();
        conn.disconnect();  //斷開(kāi)連接
        Log.i(TAG, bos.toString("utf-8"));
        return bos.toString("utf-8");
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

打印如下:

08-25 02:25:55.144: I/MainActivity(1205): {"success":"登錄成功"}

要將數(shù)據(jù)上傳到Web服務(wù)器寡具、使用Post請(qǐng)求,請(qǐng)使用配置連接進(jìn)行輸出 setDoOutput(true)稚补。
為了獲得最佳性能童叠,應(yīng)該setFixedLengthStreamingMode(int)提前知道身體長(zhǎng)度,或者setChunkedStreamingMode(int)不知道身長(zhǎng)课幕。否則HttpURLConnection將被強(qiáng)制緩沖內(nèi)存中的完整請(qǐng)求體厦坛,然后再傳輸,浪費(fèi)(可能耗盡)堆并增加延遲乍惊。
當(dāng)body長(zhǎng)度已事先知道時(shí)杜秸,應(yīng)該調(diào)用setFixedLengthStreamingMode(int),或者不知道長(zhǎng)度時(shí)調(diào)用setChunkedStreamingMode(int)润绎。 否則HttpURLConnection將被強(qiáng)制緩存內(nèi)存中的完整請(qǐng)求體撬碟,然后再傳輸,浪費(fèi)(可能耗盡)堆并增加延遲莉撇。


性能

HttpURLConnection呢蛤,此類返回的輸入和輸出流不會(huì)緩沖。大多數(shù)調(diào)用者都應(yīng)該使用BufferedInputStream或BufferedOutputStream來(lái)包裝返回的流棍郎。僅進(jìn)行批量讀取或?qū)懭氲恼{(diào)用者可以省略緩沖其障。
當(dāng)向服務(wù)器傳送大量數(shù)據(jù)或從服務(wù)器傳輸大量數(shù)據(jù)時(shí),請(qǐng)使用流來(lái)限制內(nèi)存中的數(shù)據(jù)量涂佃。除非您需要將整個(gè)數(shù)據(jù)一次存入內(nèi)存励翼,否則將其作為流處理(而不是將完整的數(shù)據(jù)存儲(chǔ)為單字節(jié)數(shù)組或字符串)。

為了減少延遲巡李,該類可以為多個(gè)請(qǐng)求/響應(yīng)對(duì)重用相同的底層Socket抚笔。 因此,HTTP連接可能會(huì)持續(xù)時(shí)間超過(guò)必要時(shí)間侨拦。 對(duì)disconnect()的調(diào)用可能會(huì)將套接字返回到連接的套接字池殊橙。 可以通過(guò)在發(fā)出任何HTTP請(qǐng)求之前將http.keepAlive系統(tǒng)屬性設(shè)置為false來(lái)禁用此行為。 http.maxConnections屬性可用于控制每個(gè)服務(wù)器將持有多少空閑連接。

默認(rèn)情況下膨蛮,HttpURLConnection請(qǐng)求服務(wù)器使用gzip壓縮叠纹。由于getContentLength()返回傳輸?shù)淖止?jié)數(shù),因此您無(wú)法使用該方法預(yù)測(cè)從getInputStream()可以讀取多少字節(jié)敞葛。而是讀取該流誉察,直到它:read()返回-1∪切常可以通過(guò)在請(qǐng)求標(biāo)頭中設(shè)置可接受的編碼來(lái)禁用Gzip壓縮:

urlConnection.setRequestProperty("Accept-Encoding", "identity");

網(wǎng)絡(luò)登錄

一些Wi-Fi網(wǎng)絡(luò)阻止Internet訪問(wèn)持偏,直到用戶點(diǎn)擊登錄頁(yè)面。 這種登錄頁(yè)面通常使用HTTP重定向來(lái)呈現(xiàn)氨肌。 您可以使用getURL()來(lái)測(cè)試您的連接是否意外重定向鸿秆。 此檢查無(wú)效,直到收到響應(yīng)標(biāo)頭怎囚,您可以通過(guò)調(diào)用getHeaderFields()或getInputStream()觸發(fā)卿叽。 例如,要檢查響應(yīng)是否未重定向到意外的主機(jī):

HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
    try {
        InputStream in = new BufferedInputStream(urlConnection.getInputStream());
    if (!url.getHost().equals(urlConnection.getURL().getHost())) {
      // we were redirected! Kick the user out to the browser to sign on?
    
    ...
    } finally {
        urlConnection.disconnect();
    }
}

歡迎大家關(guān)注恳守、評(píng)論考婴、點(diǎn)贊
你們的支持是我堅(jiān)持的動(dòng)力催烘。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末沥阱,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子颗圣,更是在濱河造成了極大的恐慌喳钟,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件在岂,死亡現(xiàn)場(chǎng)離奇詭異奔则,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)蔽午,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門易茬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人及老,你說(shuō)我怎么就攤上這事抽莱。” “怎么了骄恶?”我有些...
    開(kāi)封第一講書人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵食铐,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我僧鲁,道長(zhǎng)虐呻,這世上最難降的妖魔是什么象泵? 我笑而不...
    開(kāi)封第一講書人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮斟叼,結(jié)果婚禮上偶惠,老公的妹妹穿的比我還像新娘。我一直安慰自己朗涩,他們只是感情好忽孽,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著谢床,像睡著了一般兄一。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上萤悴,一...
    開(kāi)封第一講書人閱讀 51,688評(píng)論 1 305
  • 那天瘾腰,我揣著相機(jī)與錄音,去河邊找鬼覆履。 笑死,一個(gè)胖子當(dāng)著我的面吹牛费薄,可吹牛的內(nèi)容都是我干的硝全。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼楞抡,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼伟众!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起召廷,我...
    開(kāi)封第一講書人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤凳厢,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后竞慢,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體先紫,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年筹煮,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了遮精。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡败潦,死狀恐怖本冲,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情劫扒,我是刑警寧澤檬洞,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站沟饥,受9級(jí)特大地震影響添怔,放射性物質(zhì)發(fā)生泄漏环戈。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一澎灸、第九天 我趴在偏房一處隱蔽的房頂上張望院塞。 院中可真熱鬧,春花似錦性昭、人聲如沸拦止。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)汹族。三九已至,卻和暖如春其兴,著一層夾襖步出監(jiān)牢的瞬間顶瞒,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工元旬, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留榴徐,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓匀归,卻偏偏與公主長(zhǎng)得像坑资,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子穆端,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容