在 Flutter 中,可以使用 dart:io
包裡提供的原生的 HttpClient 來構建網路請求。
1.HttpClient 使用步驟
首先,需要匯入以下兩個 dart 包:
import 'dart:convert';
import 'dart:io';
複製程式碼
建立 HttpClient
HttpClient httpClient = HttpClient(); 複製程式碼
構建請求 uri
var uri = new Uri.http('v.juhe.cn', '/toutiao/index', {'key': '******', 'type': 'keji'}); 複製程式碼
開啟Http連線
var request = await httpClient.getUrl(uri); 複製程式碼
等待連線伺服器(會將請求資訊傳送給伺服器),請求成功後會返回 HttpClientResponse
var response = await request.close(); 複製程式碼
讀取響應內容
// 判斷 response 狀態 if (response.statusCode == HttpStatus.ok) { // 轉換 response,獲取結果 var responseBody = await response.transform(utf8.decoder).join(); } 複製程式碼
關閉client,通過該client發起的所有請求都會中止
httpClient.close(); 複製程式碼
2. 一種資料解析的方案
Flutter 禁止了 dart 中的反射!
這可能讓你請求到資料後,解析成資料類變得困難重重...
畢竟,在 Java 中的 Json 解析庫 Gson、FastJson 等內部,都依賴於反射實現。
當然, 官方推薦的方案 也不是不能用,但使用起來,實在費勁。
現在,推薦一種解析資料的方案。
在開始瞭解這種方案前,建議先看一下章節: 資料類,瞭解如何不費吹灰之力的生成 Json 可轉的資料類。
首先,在我們的專案中,介面返回的資料通常是約定好了一個最基礎的結構的,比如:
這樣的
{
"reason": "成功的返回",
"result": {
"stat": "1",
"data": ...
},
"error_code": 0
}
複製程式碼
或者這樣的
{
"reason": "成功的返回",
"data":...,
"error_code": 0
}
複製程式碼
其中,除了 data
部分是變化的,其餘部分都是固定的格式。
我們通常會封裝一個基礎的資料類,然後讓 data
部分成為動態的(比如使用一個範型來代替佔位),因為我們不想重複的定義這種結構的資料類。
以第一種結構為例,看看如何實現吧。
定義基礎資料類 Response
import 'dart:convert'; class Response{ String reason; int error_code; Result result; // parseDataFunction data 資料類的解析函式 static Response parse(String data, var parseDataFunction) { // 通過 dart:convert 提供的 jsonDecode() 函式將原始資料類轉換為 Map<String, dynamic> map var map = jsonDecode(data); Response response = Response(); response.reason = map['reason']; response.error_code = map['error_code']; response.result = Result.fromMap(map['result'], parseDataFunction); return response; } } class Result{ String stat; // 真正需要的資料類 var data; static Result fromMap(Map<String, dynamic> map, var parseDataFunction){ Result result = Result(); result.stat = map['stat']; result.data = parseDataFunction(map['data']); return result; } } 複製程式碼
其中,核心有兩點:
將動態的
data
定義為型別不定的變數就好,var
、dynamic
、Object
或者範型
都可以。傳入
data
對應的資料類解析函式,這個外掛會自動生成。
使用外掛生成
data
部分的資料類參考章節: 資料類
使用
解析普通資料類
// 傳入 fromMap 函式 Response responseData = Response.parse(responseBody, NewsData.fromMap); NewsData data = responseData.result.data; 複製程式碼
解析List型別的資料類
// 傳入 List 的 fromMapList 函式 Response responseData = Response.parse(responseBody, NewsData.fromMapList); List<NewsData> data = responseData.result.data;複製程式碼