概述
- HttpClient
- http庫(kù)
- dio庫(kù)(重點(diǎn))
一稳析、HttpClient
-
1.1、HttpClient 簡(jiǎn)介
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)容.
-
1.2毕籽、網(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://rest.apizza.net/mock/3bb78bf66bbd102a95221370ba9ddc2f/test"); // 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); } }
打印結(jié)果
flutter: {"success":"請(qǐng)求數(shù)據(jù)成功"}
提示
- 其實(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)完成蒸播。
二睡榆、http庫(kù)
-
2.1、http庫(kù),進(jìn)入鏈接:pub.dev肉微,搜索
http
http 是 Dart 官方提供的另一個(gè)網(wǎng)絡(luò)請(qǐng)求類匾鸥,相比于 HttpClient,易用性提升了不少碉纳。但是勿负,沒(méi)有默認(rèn)集成到Dart的SDK中,所以我們需要先在pubspec中依賴它:
httpdependencies: http: ^0.12.1
執(zhí)行
pub get
在使用的文件里面導(dǎo)入頭文件劳曹,并且使用即可import 'dart:io'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( // 啟動(dòng)要顯示的界面 home: HomeContent(), ); } } class HomeContent extends StatefulWidget { @override _HomeContentState createState() => _HomeContentState(); } class _HomeContentState extends State<HomeContent> { void httpNetwork() async { // 1.創(chuàng)建Client final client = http.Client(); // 2.構(gòu)建uri final url = Uri.parse("http://rest.apizza.net/mock/3bb78bf66bbd102a95221370ba9ddc2f/test"); // 3.發(fā)送請(qǐng)求 final response = await client.get(url); // 4.獲取結(jié)果 if (response.statusCode == HttpStatus.ok) { print(response.body); } else { print(response.statusCode); } } @override void initState() { // TODO: implement initState super.initState(); httpNetwork(); } @override Widget build(BuildContext context) { return Container( color: Colors.white, ); } }
打印結(jié)果
flutter: {"success":"請(qǐng)求數(shù)據(jù)成功"}
三奴愉、dio庫(kù)
3.1、 dio三方庫(kù)簡(jiǎn)介
官方提供的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í)虫溜、自定義適配器等...-
3.2雹姊、使用dio三方庫(kù)必然也需要先在pubspec中依賴它:
dio三方庫(kù)# 網(wǎng)絡(luò)請(qǐng)求的依賴 dio: ^3.0.9
基本的代碼使用
import 'dart:io'; import 'package:dio/dio.dart'; void dioNetwork() async { // 1.創(chuàng)建dio網(wǎng)絡(luò)請(qǐng)求對(duì)象 final dio = Dio(); // 2.發(fā)送網(wǎng)絡(luò)請(qǐng)求 final response = await dio.get('http://rest.apizza.net/mock/3bb78bf66bbd102a95221370ba9ddc2f/test'); // 3.打印請(qǐng)求結(jié)果 if (response.statusCode == HttpStatus.ok) { print(response.data); } else { print("請(qǐng)求失敗:${response.statusCode}"); } }
-
3.3吼渡、dio庫(kù)的封裝容为,一個(gè)配置文件:
http_config.dart
乓序,一個(gè)dio的封裝:http_request.dart
-
http_config.dart
class HttpConfig { // 基礎(chǔ)的url static const String baseUrl = ''; // 超時(shí)時(shí)間 static const int timeout = 5000; }
-
http_request.dart
import 'package:dio/dio.dart'; // 這個(gè)路徑自己配 import 'package:flutterdemo/service/http_config.dart'; class HttpRequest { static final BaseOptions baseOptions = BaseOptions(baseUrl: HttpConfig.baseUrl, connectTimeout: HttpConfig.timeout); static final Dio dio = Dio(baseOptions); // 私有方法 static Future<T> _request<T>(String url,{ String method = 'get', Map<String, dynamic> params, Interceptor inter}) async { // 1.創(chuàng)建單獨(dú)配置, 我么也可以設(shè)置 headers final options = Options(method: method, headers: {}); // 全局?jǐn)r截器 // 創(chuàng)建默認(rèn)的全局?jǐn)r截器 Interceptor dInter = InterceptorsWrapper( onRequest: (options) { print('請(qǐng)求攔截'); return options; }, onResponse: (response) { print('響應(yīng)攔截'); return response; }, onError: (err) { print('錯(cuò)誤攔截'); return err; } ); List<Interceptor> inters = [dInter]; if (inter != null) { inters.add(inter); } // 統(tǒng)一添加到攔截器中 dio.interceptors.addAll(inters); // 2.發(fā)送網(wǎng)絡(luò)請(qǐng)求 try { Response response = await dio.request(url, queryParameters: params, options: options); return response.data; } on DioError catch(e) { return Future.error(e); } } // get網(wǎng)絡(luò)請(qǐng)求 static Future<T> get<T>(String url,{ Map<String, dynamic> params, Interceptor inter}) async { return _request(url, method: 'get', params: params, inter: inter); } // post網(wǎng)絡(luò)請(qǐng)求 static Future<T> post<T>(String url,{ Map<String, dynamic> params, Interceptor inter}) async { return _request(url, method: 'post', params: params, inter: inter); }
-
-
3.4寺酪、dio庫(kù)的封裝 代碼使用:
-
get
HttpRequest.get('http://rest.apizza.net/mock/3bb78bf66bbd102a95221370ba9ddc2f/test', params: {'name': 'wc'}).then((value) { print('結(jié)果:$value'); }).catchError((error) { print('報(bào)錯(cuò)信息:$error'); });
-
post
HttpRequest.post('http://rest.apizza.net/mock/3bb78bf66bbd102a95221370ba9ddc2f/test', params: {'name': 'wc'}).then((value) { print('結(jié)果:$value'); }).catchError((error) { print('報(bào)錯(cuò)信息:$error'); });
提示
: Future<T> get<T> 中的T代表泛型
我們?cè)诰W(wǎng)絡(luò)請(qǐng)求的時(shí)候,可以傳入類型替劈,如:HttpRequest<String>.get();那么返回的類型就是 String寄雀,如果不傳類型默認(rèn)dynamic 類型
-