1. 程式人生 > >HttpClient已過時,訪問網路用HttpURLConnection(其實我自己喜歡用okhttp)

HttpClient已過時,訪問網路用HttpURLConnection(其實我自己喜歡用okhttp)

在Android 2.3及以上版本,使用的是HttpURLConnection,而在Android 2.2及以下版本,使用的是HttpClient。我也比較好奇這麼使用的原因,於是專門找到了一位Google的工程師寫的一篇部落格,文中對HttpURLConnection和HttpClient進行了對比,下面我就給大家簡要地翻譯一下。

把Android的api改到了5.1、新建了一個專案、仍然還是使用了以前的HTTP請求方式、當我把以前的程式碼複製進去之後就發現已經過時了、最後查了一下、原來是Android5.1之後就廢止了HttpClient的相關Api、但是對我們使用是沒有影響的、但是看上去總不那麼美好、後期一定要把它改了

大多數的Android應用程式都會使用HTTP協議來發送和接收網路資料,而Android中主要提供了兩種方式來進行HTTP操作,HttpURLConnection和HttpClient。這兩種方式都支援HTTPS協議、以流的形式進行上傳和下載、配置超時時間、IPv6、以及連線池等功能。

HttpClient

DefaultHttpClient和它的兄弟AndroidHttpClient都是HttpClient具體的實現類,它們都擁有眾多的API,而且實現比較穩定,bug數量也很少。
但同時也由於HttpClient的API數量過多,使得我們很難在不破壞相容性的情況下對它進行升級和擴充套件,所以目前Android團隊在提升和優化HttpClient方面的工作態度並不積極。

HttpURLConnection的使用

HTTP規範定義中最常用的請求型別就是Get和Post。當你在瀏覽器裡輸入任意一個網址按回車,瀏覽器即已經在執行Get請求了;當你回覆了某條微博時,這時可能就執行了一次Post請求。簡單的來說,Get就是向伺服器傳送索取資料的一種請求,不會影響資源的狀態;Post是向伺服器提交資料的一種請求,可能建立或更新伺服器上的資源。

      訪問伺服器連結時,需要以連結地址為引數構造生成一個java.net.URL例項。URL由網路協議、主機名、埠、資訊路徑、引用等組成統一資源定位符,它是指向網際網路“資源”的指標。資源可以是簡單的檔案或目錄,也可以是對更為複雜的物件的引用,例如對資料庫或搜尋引擎的查詢。

URL的示例程式碼如下:
URL url = new URL(“http://www.androidstar.cn:80/res/index.html#chapter1”);
      在上面的示例URL中,使用的協議為HTTP超文字傳輸協議;主機名為www.androidstar.cn;埠為80,埠值不是必須要求的,當未指定埠號時則使用協議預設的埠;資訊路徑為”res/index.html”;引用內容則是由”#”指示的”chapter1″,表示在檢索到指定的資源後,程式需要使用文件中附加有”chapter1″的標記部分。

      生成URL例項後,執行url.openConnection()方法可以獲取HttpURLConnection物件。如果URL的協議屬於以下包或其子包之一的公共、專用URLConnection子類:java.lang、java.io、java.util、java.net,則返回的連線將為該子類的型別。例如,對於HTTP,將返回HttpURLConnection,對於JAR,將返回JarURLConnection。程式碼如下:
HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
      通過程式碼獲取的HttpURLConnection預設是進行Get請求,資料只讀不提交。要使用Post方式提交資料,應提前設定好各項引數,程式碼如下:
httpConn.setDoInput(true);
httpConn.setDoOutput(true);
// 此方法在正式連結之前設定才有效。
httpConn.setRequestMethod(“POST”);
httpConn.setUseCaches(false);
// 正式建立連結
httpConn.connect();
      setDoInput(boolean)引數值為true決定著當前連結可以進行資料讀取,反之則不允許讀取操作;setDoOutput(boolean)引數值為true時決定著當前連結可以進行資料提交工作,反之則不允許。setRequestMethod(“POST”)將當前HTTP請求方式設定為”POST”,並在最後執行setUseCaches(boolean)取消了使用者快取。以上所有的工作都必須在正式建立連結之前進行。
      Post方式提交資料,需要用到資料輸出流。當執行httpConn.connect()後,即可執行httpConn.getOutputStream()獲取資料流從而進行資料寫操作,為將資料提交到伺服器作準備。程式碼如下:

DataOutputStream dos = new DataOutputStream(httpConn.getOutputStream());
String postContent = URLEncoder.encode(“channel”, “UTF-8”) + “=” + URLEncoder.encode(“Devdiv”, “UTF-8”) + “&” + URLEncoder.encode(“author”, “UTF-8”) + “=” + URLEncoder.encode(“Sodino”, “UTF-8”) ;
dos.write(postContent.getBytes());
dos.flush();
// 執行完dos.close()後,POST請求結束
dos.close();
      資料是以<Key,Value>形式提交的,為保證資料的準確性,當資料是英文字母、數字時,原樣傳送;如果是空格則轉換為”+”,如果涉及到中文或其它字元,則通過URLEncoder.encode()進行BASE 64標準轉碼,得出”%XX”格式的加工資料,其中”X”為該符號以16進製表示的ASCII碼。

      為保持資料的合法,本文所提交的內容雖皆為英文字元,但仍一致使用URLEncoder進行轉碼。當<Key,Value>數量不止一組時,組與組之間用”&”進行分隔。執行DataOutputStream.write(byte[])可以將所要提交的內容由輸出流寫入記憶體緩衝區中,在關閉輸出流之前,執行一次flush()重新整理操作,強制將可能未輸出的資料及時寫入記憶體緩衝區。

      對於同一個HttpURLConnection例項,只有執行完Post請求後,才允許Get請求進行,否則以Get請求進行的任何動作都將直接導致未執行的Post操作失敗。

      從伺服器上獲取資料,同理,需要資料輸入流,並迴圈讀取所有資料後,方可加工出使用者想要獲取的資訊。程式碼如下:

// 開始GET資料
String encoding = httpConn.getContentEncoding();
is = httpConn.getInputStream();
int read = -1;
baos = new ByteArrayOutputStream();
while ((read = is.read()) != -1) {
        baos.write(read);
}

byte[] data = baos.toByteArray();
baos.close();
String content = null;
if (encoding != null) {
        content = new String(data, encoding);
} else {
        content = new String(data);
}

      讀取過程中使用了ByteArrayOutputStream作為位元組資料的緩衝流。當InputStream.read()返回值為-1表示資料已經全部讀取完畢後,再將ByteArrayOutputStream中的緩衝資料由baos.toByteArray()一次性生成byte[],並根據一開始由httpConn.getContentEncoding()獲取的字元編碼型別,將byte[]構造成新的String。最後,所有的輸入流、輸出流都應該執行close()操作。

      在讀取資料之前,可以獲取當前連結的返回值、返回資料長度等等資訊。在單純的讀取資料中,正常的返回值RespondCode等於HTTP_OK,需要連結跳轉的返回值HTTP_MOVED_PERM/ HTTP_MOVED_TEMP,如果訪問資源不存在,則返回值HTTP_NOT_FOUND。程式碼如下:

// 獲取程式碼返回值
int respondCode = httpConn.getResponseCode()
// 獲取返回內容型別
String type = httpConn.getContentType();
// 獲取返回內容的字元編碼
String encoding = httpConn.getContentEncoding();
// 獲取返回內容長度,單位位元組
int length = httpConn.getContentLength();
// 獲取頭資訊的Key
String key = httpConn.getHeaderField(idx);
// 獲取完整的頭資訊Map
Map<String, List<String>> map = httpConn.getHeaderFields();
      以上為完整的Post/Get請求過程。
      有時在簡單的需求驅使下,伺服器開發人員出於便捷性考慮,也會將Post請求方式交由Get請求方式替代實現。以同樣需要向伺服器傳送兩組<Key,Value>資料為需求,可以將此兩組資料組合到url中,程式碼如下:
URL url = new URL(“http://www.devdiv.com:80/res/index.html?channel=Devdiv&author=sodino”);
      在完整的連結後,以”?”分隔url和傳輸資料,將<Key,Value>資料用”=”組合成字串字尾。然後依上面介紹的步驟向伺服器發起請求,亦可讀取正確的資料。同理,<Key,Value>在使用”=”組合成字串之前,仍需使用URLEncoder進行轉碼以保證資料的準確性。

      對於Post/Get所能傳送的<Key,Value>的資料量大小,HTTP 1.1中並沒有具體的限制,在實際執行中與程式執行環境及伺服器部署設定有關。

      以上介紹了Post/Get的基本使用方法,由此可看出,由於Post方式將請求的資料放置在HTTP請求的正文內,它的安全性要比Get請求的安全性要高。比如:通過Get傳送資料,使用者名稱和密碼資訊都將會出現在URL上,在設定了瀏覽器快取的情況下會被記錄導致洩漏。所以在涉及到使用者個人隱私的資料時,強烈推薦在將資料加密後使用Post方式提交至伺服器。

原文

相關推薦

HttpClient過時訪問網路HttpURLConnection(其實自己喜歡okhttp)

在Android 2.3及以上版本,使用的是HttpURLConnection,而在Android 2.2及以下版本,使用的是HttpClient。我也比較好奇這麼使用的原因,於是專門找到了一位Google的工程師寫的一篇部落格,文中對HttpURLConnection和

HttpClient過時訪問網路HttpURLConnection

最近在研究Volley框架的原始碼,發現它在HTTP請求的使用上比較有意思,在Android 2.3及以上版本,使用的是HttpURLConnection,而在Android 2.2及以下版本,使用的是HttpClient。我也比較好奇這麼使用的原因,於是專門找到了一位G

O2O過時看京東618如何用“×××零售”玩轉線上線下

AC 前端 得到 價格 可靠 mirror 帶來 終極 系列 6月19日淩晨,京東公布全球年中購物節戰報,從2018年6月1日0點到6月18日24點,累計下單金額達1592億元,其中出庫訂單金額同比增長超過37%。相比往年大打價格,促銷信息滿天飛的年中購物節,今年的 “61

人工智能風口下PHP過時Java地位也不保了!

數據分析 課程 就業市場 jsp 工程師 項目 兼容 世界 階段 PHP 從誕生到現在已經有 20 多年歷史,從 Web 時代興起到移動互聯網退潮,互聯網領域各種編程語言和技術層出不窮, Node.js 、 GO 、 Python 不斷地在挑戰 PHP 的地位。這些技術的推

代碼提交時提示文件或目錄過時請先更新

ima info 沖突 下載 分享圖片 需要 更新 部分 分享 解決方法: 將代碼更新後 再提交 如果服務器上已經有別人提交過的新的,你是提交不上去的,必須先更新再提交 更新:不會更新你已本地已修改的部分。如果svn上更新的部分和你本地修改有沖突,則會報錯,需要下載

SpringBoot2.x中WebMvcConfigurerAdapter過時使用WebMvcConfigurationSupport替換時自動配置失效

1、我們在使用SpringBoot2.x時,想要自己擴充套件SpringMvc的功能,在使用WebMvcConfigurerAdapter發現,該方法已過時。 然後通過百度,發現很多人都說可以用WebMvcConfigurationSupport來替代,於是我們很興奮的寫了一段程式碼測試。

在Mac上vmvare Fusion中的Centos7配置靜態ip訪問網路

在虛擬機器上安裝好了centos7,配置靜態ip遇到的問題,在此記錄下。我所使用的環境是mac+fusion搭建的虛擬機器。 首先是關閉防火牆 firewall-cmd --stat

警 告 System.Configuration.ConfigurationSettings.AppSettings" 過時 解 決 辦 法

背景 今天在用VS2012敲七層登陸LoginDAL層下的SQLHelper的時候出現了這樣 一個錯誤:警 告 System.Configuration.ConfigurationSettings.A

WebMvcConfigurerAdapter過時替換接口或類

res 解決方案 跳轉 extends 靜態 com xtend 問題 gis WebMvcConfigurerAdapter已經過時,在新版本2.x中被廢棄,原因是springboot2.0以後,引用的是spring5.0,而spring5.0取消了WebMvcConfi

聽說使用者故事優於例?到底該哪種方法捕獲需求?

使用者故事是敏捷開發中一種常用的需求捕獲手段,本文會先對它做個簡要介紹,再比較其和用例的不同,最後附上我的一點小體會。不想看介紹的可以直接跳到比較部分。 一、使用者故事 使用者故事(User Story):描述對軟體(或系統)使用者或客戶有價值的功能,只是需

執行登入觸發器(sql server 2016限制IP訪問)後登入sql server報錯: 由於執行觸發器,登入失敗將資料庫上下文更改為master。解決方法:cmd執行刪除登入觸發器

背景: 在cmd中執行osql命令: osql -S 【資料庫伺服器】 -E  -i  mysql.sql 其中mysql.sql內容如下: CREATE LOGIN test WITH PASSWORD = '輸入密碼' GO

Ubuntu16.04 過landeng後每次都要開啟才能訪問網路

今天用了一下landeng,然後退出後發現無法連線網路,重啟無果。 當我們開啟landeng的時候,landeng開啟了本地代理,使用的是landeng的代理。關閉landeng的時候,或者是直接關機的時候,代理設定沒有修改回來,所以我們要手動修改回來。 解決方法: s

網路連線正常訪問網路上的共享檔案時報“計算機網路斷開”錯誤

日常工作中,有的時候我們會用到ftp輸入網址,來訪問網路上的貢獻資源,但有時會遇到如下報錯:大多數時候,遇到報錯,一般是和自己電腦的IE設定有關,雙擊IE,顯示當前為離線狀態,當然不能選擇 保持離線狀態,需要點選“連線”之後,便可進行ftp訪問網路上的共享資源,前提IE的安全

httpClient訪問網路httpclient.execute(httpGet)方法不執行問題

最近在維護專案過程中遇到了一個比較奇葩的問題,軟體在別的手機上都是OK的,就是在HTC手機上的時候,會遇到軟體沒有完全退出,然後再次點選軟體,進不去的問題 首先說一下這個Bug產生的原因,因為每次 我們軟體進入的時候都去請求GuidePage,看看是否需要升級,如果需要升級

使用 HTTP 協議訪問網路的兩種方式:HttpURLConnectionHttpClient

安卓中進行基於HTTP協議的網路訪問 說明: HttpClient (apache開發) HttpURLConnection(google在釋出安卓時在Java基礎上修改得到的) 使用HC(HttpClient)/UC(HttpURLConnect

HttpClient(訪問網路) get方式post方式。返回值有String,InputStream,byte[]

import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.ut

C#域賬號登陸訪問網絡路徑

dto err sid cti pan sin spa tool oid 使用域賬號登陸,訪問網絡路徑 1 public class FileTool : IDisposable 2 { 3 [DllImport("kernel32.dll", CharSet =

Python + Appium 【解決】driver(session)在多個class之間復執行完一個類的再次執行下個類的例時不需要初始化

nic bject config com appium client lee session ted py文件的名稱為:appium_config.py 中的寫法如下 # coding=UTF-8 ‘‘‘ Created on 2017.1.13 @author: Lu

5.Apache戶認證,域名跳轉訪問日誌

用戶認證 域名跳轉 訪問日誌 [toc] Apache用戶認證 11.18 Apache用戶認證 用戶認證功能就是在用戶訪問網站的時候,需要輸入用戶名密碼才能進行訪問。一些比較好總要的站點和網站後臺都會加上用戶認證,以保證安全。 1.下面對xavi.com站點來做一個全站的用戶認證: vim

http的戶認證域名跳轉訪問日誌

http用戶認證 域名跳轉 訪問日誌 httpd的用戶認證 網站的特殊頁面需要二級認證 vim /usr/local/apache2.4/conf/extra/httpd-vhosts.conf //編輯111.com虛擬主機 <VirtualHost *:80> Document