1. 程式人生 > 實用技巧 >基於 HttpURLConnection 的網路開發總結

基於 HttpURLConnection 的網路開發總結

1.HttpURLConnection 上傳進度

用HttpURLConnection 做檔案上傳,會有需要顯示上傳進度的需求。但是根據官方的文件說明,如下圖,HttpURLConnection 在上傳資料之前,預設會強制先將請求體快取在記憶體中。這樣會導致我們上傳進度顯示不準確。具體現象就是上傳進度早早顯示上傳完成,但是上傳網路請求還遲遲未結束。

至於解決方式,上面圖片中前一句官方給出答案,可以呼叫setFixedLengthStreamingMode方法或者setChunkedStreamingMode 方法去禁用掉HttpURLConnection 的上傳快取,這樣進度就顯示正確。

public
void setFixedLengthStreamingMode (int contentLength) public void setChunkedStreamingMode (int chunklen)

但是setChunkedStreamingMode 方法並不是被所有伺服器都支援,所以我們捨棄了這種方式。

處理示例:

int contentLength = 1;
int uploadLength = 0;
if (listener != null) {
   contentLength = getContentLength(requestParams, boundary, filePaths);
   
//禁用 HttpURLConnection 上傳快取 connection.setFixedLengthStreamingMode(contentLength); } ...... //在寫入的地方呼叫 out.write(bytes); if (listener != null) { float totalLen = contentLength * 1.0f; uploadLength += bytes.length; int progress = Math.round((uploadLength / totalLen) * 100); listener.onProgress(progress); }

2.HttpURLConnection 接收伺服器返回資料

這裡我們需要考慮的點有以下幾點:

  • 資料編碼
  • 資料型別
  • 資料是否壓縮

1. 資料編碼以及資料型別

使用正確的編碼格式,才能正確接收伺服器返回的資料,否則會出現亂碼的情況。

獲取響應體編碼:

//第一種方式,這種方式或者的是相同field的最後一個值
String contentEncoding = connection.getHeaderField("Content-Type");
//第二種方式,這種方式確認是從response中獲取。遍歷獲得
Map<String, List<String>> headerFields = connection.getHeaderFields();

示例值:Content-Type: text/html;charset=UTF-8

2. 資料是否壓縮

如果伺服器返回的資料是採用了某種壓縮格式後傳輸的,我們直接採用正確的編碼直接從資料流讀取資料,也會產生亂碼。這個時候我們要轉成對應壓縮資料流去讀取。

首先我們先判斷服務返回資料是否採用壓縮:

String contentEncoding = connection.getHeaderField("Content-Encoding");
InputStream inputStream = connection.getInputStream();
// 處理介面返回gzip資料
if (!TextUtils.isEmpty(contentEncoding) && "gzip".equalsIgnoreCase(contentEncoding)) {
   inputStream = new GZIPInputStream(inputStream);
}

示例 Header :Content-Encoding: gzip