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

概述

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

    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(
              // 啟動(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 類型

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市陨献,隨后出現(xiàn)的幾起案子盒犹,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,000評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件急膀,死亡現(xiàn)場(chǎng)離奇詭異沮协,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)卓嫂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門慷暂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人晨雳,你說(shuō)我怎么就攤上這事行瑞。” “怎么了餐禁?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,561評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵血久,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我帮非,道長(zhǎng)氧吐,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,782評(píng)論 1 298
  • 正文 為了忘掉前任末盔,我火速辦了婚禮副砍,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘庄岖。我一直安慰自己豁翎,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,798評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布隅忿。 她就那樣靜靜地躺著心剥,像睡著了一般。 火紅的嫁衣襯著肌膚如雪背桐。 梳的紋絲不亂的頭發(fā)上优烧,一...
    開(kāi)封第一講書(shū)人閱讀 52,394評(píng)論 1 310
  • 那天,我揣著相機(jī)與錄音链峭,去河邊找鬼畦娄。 笑死,一個(gè)胖子當(dāng)著我的面吹牛弊仪,可吹牛的內(nèi)容都是我干的熙卡。 我是一名探鬼主播,決...
    沈念sama閱讀 40,952評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼励饵,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼驳癌!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起役听,我...
    開(kāi)封第一講書(shū)人閱讀 39,852評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤颓鲜,失蹤者是張志新(化名)和其女友劉穎表窘,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體甜滨,經(jīng)...
    沈念sama閱讀 46,409評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡乐严,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,483評(píng)論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了衣摩。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片麦备。...
    茶點(diǎn)故事閱讀 40,615評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖昭娩,靈堂內(nèi)的尸體忽然破棺而出凛篙,到底是詐尸還是另有隱情,我是刑警寧澤栏渺,帶...
    沈念sama閱讀 36,303評(píng)論 5 350
  • 正文 年R本政府宣布呛梆,位于F島的核電站,受9級(jí)特大地震影響磕诊,放射性物質(zhì)發(fā)生泄漏呜师。R本人自食惡果不足惜胯盯,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,979評(píng)論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧翁垂,春花似錦膏秫、人聲如沸提佣。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,470評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)广凸。三九已至阅茶,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間谅海,已是汗流浹背脸哀。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,571評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留扭吁,地道東北人撞蜂。 一個(gè)月前我還...
    沈念sama閱讀 49,041評(píng)論 3 377
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像侥袜,于是被迫代替她去往敵國(guó)和親蝌诡。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,630評(píng)論 2 359