????項(xiàng)目中展示的大部分?jǐn)?shù)據(jù)都是來(lái)自服務(wù)器砾赔,我們需要向服務(wù)器請(qǐng)求數(shù)據(jù),并且對(duì)他們進(jìn)行解析展示。
????向服務(wù)器發(fā)出請(qǐng)求就需要用到網(wǎng)絡(luò)請(qǐng)求相關(guān)的知識(shí)佳恬。
一. 網(wǎng)絡(luò)請(qǐng)求的方式
在Flutter中常見的網(wǎng)絡(luò)請(qǐng)求方式有三種:HttpClient、http庫(kù)于游、dio庫(kù)殿怜;
1.1. HttpClient
HttpClient是dart自帶的請(qǐng)求類,在io包中曙砂,實(shí)現(xiàn)了基本的網(wǎng)絡(luò)請(qǐng)求相關(guān)的操作头谜。
網(wǎng)絡(luò)調(diào)用通常遵循如下步驟:
????創(chuàng)建 client.
????構(gòu)造 Uri.
????發(fā)起請(qǐng)求, 等待請(qǐng)求,同時(shí)您也可以配置請(qǐng)求headers鸠澈、 body柱告。
????關(guān)閉請(qǐng)求, 等待響應(yīng).
????解碼響應(yīng)的內(nèi)容.
網(wǎng)絡(luò)請(qǐng)求實(shí)例:
void requestNetwork() async {
? // 1.創(chuàng)建HttpClient對(duì)象
? final httpClient = HttpClient();
? // 2.構(gòu)建請(qǐng)求的uri
? final uri = Uri.parse("http://123.207.32.32:8000/api/v1/recommend");
? // 3.構(gòu)建請(qǐng)求
? final request = await httpClient.getUrl(uri);
? // 4.發(fā)送請(qǐng)求,必須
? final response = await request.close();
? if (response.statusCode == HttpStatus.ok) {
? ? print(await response.transform(utf8.decoder).join());
? } else {
? ? print(response.statusCode);
? }
}
OK笑陈,其實(shí)HttpClient也可以發(fā)送post相關(guān)的請(qǐng)求际度,我們這里就不再演練。
HttpClient雖然可以發(fā)送正常的網(wǎng)絡(luò)請(qǐng)求涵妥,但是會(huì)暴露過(guò)多的細(xì)節(jié):
????比如需要主動(dòng)關(guān)閉request請(qǐng)求乖菱,拿到數(shù)據(jù)后也需要手動(dòng)的進(jìn)行字符串解碼
在開發(fā)中,我們一般很多直接面向HttpClient進(jìn)行網(wǎng)絡(luò)請(qǐng)求蓬网,而是使用一些庫(kù)來(lái)完成窒所。
1.2. http庫(kù)
http 是 Dart 官方提供的另一個(gè)網(wǎng)絡(luò)請(qǐng)求類,相比于 HttpClient帆锋,易用性提升了不少吵取。
但是,沒有默認(rèn)集成到Dart的SDK中锯厢,所以我們需要先在pubspec中依賴它:
? http:^0.12.0+2
導(dǎo)入并且使用即可
import'package:http/http.dart'as http;
void httpNetwork() async {
? // 1.創(chuàng)建Client
? final client = http.Client();
? // 2.構(gòu)建uri
? final url = Uri.parse("http://123.207.32.32:8000/api/v1/recommend");
? // 3.發(fā)送請(qǐng)求
? final response = await client.get(url);
? // 4.獲取結(jié)果
? if (response.statusCode == HttpStatus.ok) {
? ? print(response.body);
? } else {
? ? print(response.statusCode);
? }
}
1.3. dio三方庫(kù)
官方提供的HttpClient和http都可以正常的發(fā)送網(wǎng)絡(luò)請(qǐng)求皮官,但是對(duì)于現(xiàn)代的應(yīng)用程序開發(fā)來(lái)說(shuō),我們通常要求的東西會(huì)更多:比如攔截器实辑、取消請(qǐng)求捺氢、文件上傳/下載、超時(shí)設(shè)置等等剪撬;
這個(gè)時(shí)候摄乒,我們可以使用一個(gè)在Flutter中非常流行的三方庫(kù):dio;
官網(wǎng)有對(duì)dio進(jìn)行解釋:
????dio是一個(gè)強(qiáng)大的Dart Http請(qǐng)求庫(kù),支持Restful API缺狠、FormData问慎、攔截器、請(qǐng)求取消挤茄、Cookie管理如叼、文件上傳/下載、超時(shí)穷劈、自定義適配器等...
使用dio三方庫(kù)必然也需要先在pubspec中依賴它:
? dio:^3.0.1
代碼演練:
import'package:dio/dio.dart';
void dioNetwork() async {
? // 1.創(chuàng)建Dio請(qǐng)求對(duì)象
? final dio = Dio();
? // 2.發(fā)送網(wǎng)絡(luò)請(qǐng)求
? final response = await dio.get("http://123.207.32.32:8000/api/v1/recommend");
? // 3.打印請(qǐng)求結(jié)果
? if (response.statusCode == HttpStatus.ok) {
? ? print(response.data);
? } else {
? ? print("請(qǐng)求失斄 :${response.statusCode}");
? }
}
1.4. dio庫(kù)的封裝
http_config.dart
class HTTPConfig {
? staticconst baseURL = "https://httpbin.org";
? staticconst timeout = 5000;
}
http_request.dart
import'package:dio/dio.dart';
import'package:testflutter001/service/config.dart';
class HttpRequest {
? staticfinal BaseOptions options = BaseOptions(
? ? ? baseUrl: HTTPConfig.baseURL, connectTimeout: HTTPConfig.timeout);
? staticfinal Dio dio = Dio(options);
? static Future<T> request<T>(String url,
? ? ? {String method = 'get', Map<String, dynamic> params, Interceptor inter}) async {
? ? // 1.請(qǐng)求的單獨(dú)配置
? ? final options = Options(method: method);
? ? // 2.添加第一個(gè)攔截器
? ? Interceptor dInter = InterceptorsWrapper(
? ? ? onRequest: (RequestOptions options) {
? ? ? ? // 1.在進(jìn)行任何網(wǎng)絡(luò)請(qǐng)求的時(shí)候, 可以添加一個(gè)loading顯示
? ? ? ? // 2.很多頁(yè)面的訪問(wèn)必須要求攜帶Token,那么就可以在這里判斷是有Token
? ? ? ? // 3.對(duì)參數(shù)進(jìn)行一些處理,比如序列化處理等
? ? ? ? print("攔截了請(qǐng)求");
? ? ? ? return options;
? ? ? },
? ? ? onResponse: (Response response) {
? ? ? ? print("攔截了響應(yīng)");
? ? ? ? return response;
? ? ? },
? ? ? onError: (DioError error) {
? ? ? ? print("攔截了錯(cuò)誤");
? ? ? ? return error;
? ? ? }
? ? );
? ? List<Interceptor> inters = [dInter];
? ? if (inter != null) {
? ? ? inters.add(inter);
? ? }
? ? dio.interceptors.addAll(inters);
? ? // 3.發(fā)送網(wǎng)絡(luò)請(qǐng)求
? ? try {
? ? ? Response response = await dio.request<T>(url, queryParameters: params, options: options);
? ? ? return response.data;
? ? } on DioError catch(e) {
? ? ? return Future.error(e);
? ? }
? }
}
代碼使用:
HttpRequest.request("https://httpbin.org/get", params: {"name": "why", 'age': 18}).then((res) {
? print(res);
});
HttpRequest.request("https://httpbin.org/post",
? ? ? ? ? ? ? ? ? ? method: "post", params: {"name": "why", 'age': 18}).then((res) {
? print(res);
});