Day09 - Flutter -網(wǎng)絡(luò)請求的封裝

概述

  • 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中依賴它:

    http

    dependencies:
       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 類型

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

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