在 Flutter 中,可使用 dart:io
包裏提供的原生的 HttpClient 來構建網絡請求。github
首先,須要導入如下兩個 dart 包:json
import 'dart:convert';
import 'dart:io';
複製代碼
建立 HttpClientbash
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();
複製代碼
讀取響應內容post
// 判斷 response 狀態
if (response.statusCode == HttpStatus.ok) {
// 轉換 response,獲取結果
var responseBody = await response.transform(utf8.decoder).join();
}
複製代碼
關閉client,經過該client發起的全部請求都會停止ui
httpClient.close();
複製代碼
Flutter 禁止了 dart 中的反射!spa
這可能讓你請求到數據後,解析成數據類變得困難重重...
畢竟,在 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;複製代碼