Day09 - Flutter -网络请求的封装

概述

  • HttpClient
  • http库
  • dio库(重点)
一、HttpClient
  • 1.1、HttpClient 简介
    HttpClient是dart自带的请求类,在io包中,实现了基本的网络请求相关的操作。
    网络调用通常遵循如下步骤:

    • 创建 client.
    • 构造 Uri.
    • 发起请求, 等待请求,同时您也可以配置请求headers、 body。
    • 关闭请求, 等待响应.
    • 解码响应的内容.
  • 1.2、网络请求实例

    void requestNetwork() async {
       // 1.创建HttpClient对象
       final httpClient = HttpClient();
    
       // 2.构建请求的uri
       final uri = Uri.parse("http://rest.apizza.net/mock/3bb78bf66bbd102a95221370ba9ddc2f/test");
    
       // 3.构建请求
       final request = await httpClient.getUrl(uri);
    
       // 4.发送请求,必须
       final response = await request.close();
       if (response.statusCode == HttpStatus.ok) {
           print(await response.transform(utf8.decoder).join());
       } else {
           print(response.statusCode);
       }
    }
    

    打印结果

    flutter: {"success":"请求数据成功"}
    
    • 提示
    • 其实HttpClient也可以发送post相关的请求
    • HttpClient虽然可以发送正常的网络请求,但是会暴露过多的细节:
    • 比如需要主动关闭request请求,拿到数据后也需要手动的进行字符串解码
      在开发中,我们一般很多直接面向HttpClient进行网络请求,而是使用一些库来完成。
二、http库
  • 2.1、http库,进入链接:pub.dev,搜索 http
    http 是 Dart 官方提供的另一个网络请求类,相比于 HttpClient,易用性提升了不少。但是,没有默认集成到Dart的SDK中,所以我们需要先在pubspec中依赖它:

    http

    dependencies:
       http: ^0.12.1
    

    执行 pub get
    在使用的文件里面导入头文件,并且使用即可

    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.创建Client
          final client = http.Client();
    
          // 2.构建uri
          final url = Uri.parse("http://rest.apizza.net/mock/3bb78bf66bbd102a95221370ba9ddc2f/test");
    
          // 3.发送请求
          final response = await client.get(url);
    
          // 4.获取结果
          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,
         );
       }
    }
    

    打印结果

     flutter: {"success":"请求数据成功"}
    
三、dio库
  • 3.1、 dio三方库简介
    官方提供的HttpClient和http都可以正常的发送网络请求,但是对于现代的应用程序开发来说,我们通常要求的东西会更多:比如拦截器、取消请求、文件上传/下载、超时设置等等;
    这个时候,我们可以使用一个在Flutter中非常流行的三方库:dio;
    官网有对dio进行解释:dio是一个强大的Dart Http请求库,支持Restful API、FormData、拦截器、请求取消、Cookie管理、文件上传/下载、超时、自定义适配器等...

  • 3.2、使用dio三方库必然也需要先在pubspec中依赖它:


    dio三方库
    # 网络请求的依赖
    dio: ^3.0.9
    

    基本的代码使用

    import 'dart:io';
    import 'package:dio/dio.dart';
    
    void dioNetwork() async {
    
       // 1.创建dio网络请求对象
       final dio = Dio();
    
       // 2.发送网络请求
       final response = await dio.get('http://rest.apizza.net/mock/3bb78bf66bbd102a95221370ba9ddc2f/test');
    
       // 3.打印请求结果
       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 {
         // 基础的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.创建单独配置, 我么也可以设置 headers
              final options = Options(method: method, headers: {});
      
              // 全局拦截器
              // 创建默认的全局拦截器
              Interceptor dInter = InterceptorsWrapper(
                 onRequest: (options) {
                    print('请求拦截');
                    return options;
                 },
                 onResponse: (response) {
                    print('响应拦截');
                    return response;
                 },
                 onError: (err) {
                    print('错误拦截');
                    return err;
                 }
              );
      
              List<Interceptor> inters = [dInter];
              if (inter != null) {
                 inters.add(inter);
              }
              // 统一添加到拦截器中
              dio.interceptors.addAll(inters);
      
              // 2.发送网络请求
              try {
                 Response response = await dio.request(url, queryParameters: params, options: options);
                 return response.data;
              } on DioError catch(e) {
                 return Future.error(e);
              }
           }
      
           // get网络请求
          static Future<T> get<T>(String url,{
                                  Map<String, dynamic> params, Interceptor inter}) async {
               return _request(url, method: 'get', params: params, inter: inter);
          }
          // post网络请求
          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('结果:$value');
      }).catchError((error) {
           print('报错信息:$error');
      });
      
    • post

      HttpRequest.post('http://rest.apizza.net/mock/3bb78bf66bbd102a95221370ba9ddc2f/test', params: {'name': 'wc'}).then((value) {
           print('结果:$value');
      }).catchError((error) {
           print('报错信息:$error');
      });
      

      提示: Future<T> get<T> 中的T代表泛型
      我们在网络请求的时候,可以传入类型,如:HttpRequest<String>.get();那么返回的类型就是 String,如果不传类型默认dynamic 类型

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270