Flutter開(kāi)發(fā)(10)- 網(wǎng)絡(luò)請(qǐng)求

????項(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中常見(jiàn)的網(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)行字符串解碼

在開(kāi)發(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,易用性提升了不少。

但是,沒(méi)有默認(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)用程序開(kāi)發(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);

});

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容