美文网首页Flutter初探
Day09 - Flutter -网络请求的封装

Day09 - Flutter -网络请求的封装

作者: IIronMan | 来源:发表于2020-05-25 14:01 被阅读0次

    概述

    • 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 类型

    相关文章

      网友评论

        本文标题:Day09 - Flutter -网络请求的封装

        本文链接:https://www.haomeiwen.com/subject/syetahtx.html