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

    Day09 - Flutter -网络请求的封装_第1张图片
    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 {
    
       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中依赖它:


    Day09 - Flutter -网络请求的封装_第2张图片
    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 _request(String url,{
                   String method = 'get',
                   Map 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 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 get(String url,{
                                  Map params, Interceptor inter}) async {
               return _request(url, method: 'get', params: params, inter: inter);
          }
          // post网络请求
          static Future post(String url,{
                                   Map 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 get 中的T代表泛型
      我们在网络请求的时候,可以传入类型,如:HttpRequest.get();那么返回的类型就是 String,如果不传类型默认dynamic 类型

你可能感兴趣的:(Day09 - Flutter -网络请求的封装)