概述
- HttpClient
- http庫
- dio庫(重點)
一、HttpClient
-
1.1、HttpClient 簡介
HttpClient是dart自帶的請求類,在io包中,實現(xiàn)了基本的網(wǎng)絡(luò)請求相關(guān)的操作。
網(wǎng)絡(luò)調(diào)用通常遵循如下步驟:- 創(chuàng)建 client.
- 構(gòu)造 Uri.
- 發(fā)起請求, 等待請求,同時您也可以配置請求headers、 body。
- 關(guān)閉請求, 等待響應(yīng).
- 解碼響應(yīng)的內(nèi)容.
-
1.2、網(wǎng)絡(luò)請求實例
void requestNetwork() async { // 1.創(chuàng)建HttpClient對象 final httpClient = HttpClient(); // 2.構(gòu)建請求的uri final uri = Uri.parse("http://rest.apizza.net/mock/3bb78bf66bbd102a95221370ba9ddc2f/test"); // 3.構(gòu)建請求 final request = await httpClient.getUrl(uri); // 4.發(fā)送請求,必須 final response = await request.close(); if (response.statusCode == HttpStatus.ok) { print(await response.transform(utf8.decoder).join()); } else { print(response.statusCode); } }打印結(jié)果
flutter: {"success":"請求數(shù)據(jù)成功"}提示- 其實HttpClient也可以發(fā)送post相關(guān)的請求
- HttpClient雖然可以發(fā)送正常的網(wǎng)絡(luò)請求,但是會暴露過多的細(xì)節(jié):
- 比如需要主動關(guān)閉request請求,拿到數(shù)據(jù)后也需要手動的進(jìn)行字符串解碼
在開發(fā)中,我們一般很多直接面向HttpClient進(jìn)行網(wǎng)絡(luò)請求,而是使用一些庫來完成。
二、http庫
-
2.1、http庫,進(jìn)入鏈接:pub.dev,搜索
http
http 是 Dart 官方提供的另一個網(wǎng)絡(luò)請求類,相比于 HttpClient,易用性提升了不少。但是,沒有默認(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( // 啟動要顯示的界面 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ā)送請求 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":"請求數(shù)據(jù)成功"}
三、dio庫
3.1、 dio三方庫簡介
官方提供的HttpClient和http都可以正常的發(fā)送網(wǎng)絡(luò)請求,但是對于現(xiàn)代的應(yīng)用程序開發(fā)來說,我們通常要求的東西會更多:比如攔截器、取消請求、文件上傳/下載、超時設(shè)置等等;
這個時候,我們可以使用一個在Flutter中非常流行的三方庫:dio;
官網(wǎng)有對dio進(jìn)行解釋:dio是一個強(qiáng)大的Dart Http請求庫,支持Restful API、FormData、攔截器、請求取消、Cookie管理、文件上傳/下載、超時、自定義適配器等...-
3.2、使用dio三方庫必然也需要先在pubspec中依賴它:
dio三方庫# 網(wǎng)絡(luò)請求的依賴 dio: ^3.0.9基本的代碼使用
import 'dart:io'; import 'package:dio/dio.dart'; void dioNetwork() async { // 1.創(chuàng)建dio網(wǎng)絡(luò)請求對象 final dio = Dio(); // 2.發(fā)送網(wǎng)絡(luò)請求 final response = await dio.get('http://rest.apizza.net/mock/3bb78bf66bbd102a95221370ba9ddc2f/test'); // 3.打印請求結(jié)果 if (response.statusCode == HttpStatus.ok) { print(response.data); } else { print("請求失?。?{response.statusCode}"); } } -
3.3、dio庫的封裝,一個配置文件:
http_config.dart,一個dio的封裝:http_request.dart-
http_config.dart
class HttpConfig { // 基礎(chǔ)的url static const String baseUrl = ''; // 超時時間 static const int timeout = 5000; } -
http_request.dart
import 'package:dio/dio.dart'; // 這個路徑自己配 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)建單獨配置, 我么也可以設(shè)置 headers final options = Options(method: method, headers: {}); // 全局?jǐn)r截器 // 創(chuàng)建默認(rèn)的全局?jǐn)r截器 Interceptor dInter = InterceptorsWrapper( onRequest: (options) { print('請求攔截'); return options; }, onResponse: (response) { print('響應(yīng)攔截'); return response; }, onError: (err) { print('錯誤攔截'); return err; } ); List<Interceptor> inters = [dInter]; if (inter != null) { inters.add(inter); } // 統(tǒng)一添加到攔截器中 dio.interceptors.addAll(inters); // 2.發(fā)送網(wǎng)絡(luò)請求 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ò)請求 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ò)請求 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庫的封裝 代碼使用:
-
get
HttpRequest.get('http://rest.apizza.net/mock/3bb78bf66bbd102a95221370ba9ddc2f/test', params: {'name': 'wc'}).then((value) { print('結(jié)果:$value'); }).catchError((error) { print('報錯信息:$error'); }); -
post
HttpRequest.post('http://rest.apizza.net/mock/3bb78bf66bbd102a95221370ba9ddc2f/test', params: {'name': 'wc'}).then((value) { print('結(jié)果:$value'); }).catchError((error) { print('報錯信息:$error'); });提示: Future<T> get<T> 中的T代表泛型
我們在網(wǎng)絡(luò)請求的時候,可以傳入類型,如:HttpRequest<String>.get();那么返回的類型就是 String,如果不傳類型默認(rèn)dynamic 類型
-

