Flutter 学习之DIO封装

2023-05-16

简介:

需要导入的库

dio: ^3.0.9
json_serializable: ^3.3.0
dio_cookie_manager: ^1.0.0
dio_http_cache: ^0.2.6

介绍:
在自己的这个封装中集成了

  • 显示日志
  • 缓存cooker
  • 缓存结果

##代码

import 'dart:convert';
import 'package:chuanzhi/contract/api.dart';
import 'package:chuanzhi/contract/config.dart';
import 'package:dio/dio.dart';
import 'package:cookie_jar/cookie_jar.dart';
import 'package:dio_cookie_manager/dio_cookie_manager.dart';
import 'package:dio_http_cache/dio_http_cache.dart';

/// 网络请求的工具类,通过这个方法可以获取到请求成功与请求失败的回调(Respose类)。
class HttpUtils {
  /// get 请求的方式
  static const String _getRequestMethod = 'get';

  /// post 请求的方式
  static const String _postRequestMethod = 'post';

  /// 创建dio这个网络框架
  Dio _dio = Dio();

  /// 私有化的HttpUtils 的实例
  static HttpUtils _instace;
  bool _showDebug;
  bool _showCache;

  /// httpUtils 的的单例方法
  /// 参数:
  /// Map<String, dynamic> headers : 请求头,此请求头可以不传递。
  /// String baseUrl : baseUrl ,这个baseurl 方法可以替换。当然如果是在真实项目中baseUrl 一般都是一致的。所以此参数可以不传递
  /// int connectTimeouts :请求的超时时间,此参数默认是5000,大家可以对于访问数据多的设置此参数,参数可以不传递。
  /// int receiveTimeouts : 响应的超时时间,此参数默认为3000,参数可以不传递。
  static HttpUtils getInstace(
      [Map<String, dynamic> headers,
      String baseUrl = APIURL.BASE_URL,
      int connectTimeouts = 5000,
      int receiveTimeouts = 3000,
      bool showDebug = Config.isShowDebug,
      bool showCooker = Config.showCooker,
      bool showCache = Config.showCache]) {
    if (_instace == null) {
      _instace = HttpUtils._(headers, baseUrl, connectTimeouts, receiveTimeouts,
          showDebug, showCooker, showCache);
    }
    return _instace;
  }

  /// 私有化构造方法,只可以通过 getInstace 的空参构造获取到HttpUtils 的实例。
  HttpUtils._(Map<String, dynamic> headers, String baseUrl, int connectTimeouts,
      int receiveTimeouts, bool showDebug, bool showCooker, bool showCache) {
    ///1. 如果有header 头,那么就设置,如果没有的话,就不设置
    if (headers != null && headers.isNotEmpty) {
      _dio.options.headers = headers;
    }

    /// 2. 设置超时时间
    _dio.options.baseUrl = baseUrl;

    /// 3. 设置请求的超时时间
    _dio.options.connectTimeout = connectTimeouts;

    ///4.设置接受的超时时间
    _dio.options.receiveTimeout = receiveTimeouts;

    /// 5.设置是否显示Log日志,默认为false
    _dio.interceptors.add(LogInterceptor(responseBody: showDebug));
    _showDebug = showDebug;

    if (showCooker) {
      /// 6. 设置缓存
      _dio.interceptors.add(CookieManager(CookieJar()));
    }
    _showCache = showCache;
    if (_showCache) {
      _dio.interceptors
          .add(DioCacheManager(CacheConfig(baseUrl: baseUrl)).interceptor);
    }
  }

  /// get 请求的方法
  /// String path : 此参数是baseUrl 之后的内容。必须要传递
  ///  Function successCallBack: 此参数是成功的回调
  ///   Function errCallBack: 此参数是失败的回调
  ///  Map<String,dynamic> params : 请求的参数,此参数不是必须要传的参数,因为某些请求中没有需要传递的参数。
  get(String path, Function successCallBack, Function errCallBack,
      [Map<String, dynamic> params, int days = 7]) {
    _httprequest(
        path, _getRequestMethod, successCallBack, errCallBack, params, days);
  }

  /// post 请求的方法 , 此方法和上面的get 方法类似 。
  post(String path, Map<String, dynamic> params, Function successCallBack,
      Function errCallBack,
      [int days = 7]) {
    _httprequest(
        path, _postRequestMethod, successCallBack, errCallBack, params, days);
  }

  /// http 请求的实现方法
  ///
  _httprequest(
    String path,
    String method,
    Function successCallBack,
    Function errCallBack,
    Map<String, dynamic> params,
    int days,
  ) async {
    Response _response;
    Map<String, dynamic> headers = _dio.options.headers;
    try {
      /// get 请求方式
      if (_getRequestMethod == method) {
        if (_showCache) {
          if (params != null && params.isNotEmpty) {
            /// get 请求有参数
            _response = await _dio.get(path,
                queryParameters: params,
                options: buildCacheOptions(Duration(days: days)));
          } else {
            /// get 请求无参数
            _response = await _dio.get(path,
                options: buildCacheOptions(Duration(days: days)));
          }
        } else {
          if (params != null && params.isNotEmpty) {
            /// get 请求有参数
            _response = await _dio.get(path, queryParameters: params);
          } else {
            /// get 请求无参数
            _response = await _dio.get(path);
          }
        }
      } else

      /// post 请求方式
      if (_postRequestMethod == method) {
        if (_showCache) {
          if (params != null && params.isNotEmpty) {
            _response = await _dio.post(path,
                queryParameters: params,
                options: buildCacheOptions(Duration(days: days)));
          } else {
            _response = await _dio.post(path,
                options: buildCacheOptions(Duration(days: days)));
          }
        } else {
          if (params != null && params.isNotEmpty) {
            _response = await _dio.post(path, queryParameters: params);
          } else {
            _response = await _dio.post(path);
          }
        }
      }
    } on DioError catch (error) {
      // 请求错误处理
      Response errorResponse;
      if (error.response != null) {
        errorResponse = error.response;
      } else {
        /// 555 : 代表的是自己的错误
        errorResponse = new Response(statusCode: 555);
      }
      // 请求超时
      if (error.type == DioErrorType.CONNECT_TIMEOUT) {
        errorResponse.statusCode = ResultCode.CONNECT_TIMEOUT;
      }
      // 一般服务器错误
      else if (error.type == DioErrorType.RECEIVE_TIMEOUT) {
        errorResponse.statusCode = ResultCode.RECEIVE_TIMEOUT;
      }
      // debug模式才打印
      if (_showDebug) {
        print('请求异常: ' + error.toString());
        print('请求异常url: ' + path);

        if (headers != null && headers.isNotEmpty) {
          print('请求头: ' + headers.toString());
        }
        print('method: ' + _dio.options.method);
      }
      _error(errCallBack, error.message);
      return '';
    }
    // debug模式打印相关数据
    if (_showDebug) {
      print('请求url: ' + path);
      if (headers != null && headers.isNotEmpty) {
        print('请求头: ' + headers.toString());
      }
      if (params != null && params.isNotEmpty) {
        print('请求参数: ' + params.toString());
      }
      if (_response != null) {
        print('返回参数: ' + _response.toString());
      }
    }
    Map<String, dynamic> dataMap = json.decode(_response.data);
    if (dataMap == null || dataMap['state'] == 0) {
      _error(
          errCallBack,
          '错误码:' +
              dataMap['errorCode'].toString() +
              ',' +
              _response.data.toString());
    } else if (successCallBack != null) {
      successCallBack(dataMap);
    }
  }

  /// 异常的类
  _error(Function errorCallBack, String error) {
    if (errorCallBack != null) {
      errorCallBack(error);
    }
  }
}

class ResultCode {
  //正常返回是1
  static const SUCCESS = 1;

  //异常返回是0
  static const ERROR = 1;

  /// When opening  url timeout, it occurs.
  static const CONNECT_TIMEOUT = -1;

  ///It occurs when receiving timeout.
  static const RECEIVE_TIMEOUT = -2;

  /// When the server response, but with a incorrect status, such as 404, 503...
  static const RESPONSE = -3;

  /// When the request is cancelled, dio will throw a error with this type.
  static const CANCEL = -4;

  /// read the DioError.error if it is not null.
  static const DEFAULT = -5;
}

class Config {
  Config._();
  /// 是否显示Debug 日志
  static const bool isShowDebug = false;

  /// 是否保存Cooker
  static const bool showCooker = false;

  /// 是否使用缓存
  static const bool showCache = true;
}

使用

    Map<String, String> map = Map();
    map['device'] = 'android';
    HttpUtils.getInstace().get(
      APIURL.GET_DECODE,
      (data) {
        print('获取数据成功');
        print(data);
      },
      (error) {
        print('获取数据失败');
        print(error);
      },
      map,
    );

想法:

大家会说这里好多都用不上啊,我只想说以后扩展起来方便。最惭愧的是我自己不自量力的想要修改回调的方法。结果发现,果然自己还是没有办法让回调成功和回调失败都必须传递参数。所以,有哪位大神知道,请在下方告诉我。

在这里感谢 浩仔-Boy写的文章。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Flutter 学习之DIO封装 的相关文章

随机推荐

  • Spring之Spring概念

    什么是Spring xff1f 1 Spring是轻量级的开源的JavaEE框架 2 Spring可以解决企业应用开发的复杂性 3 Spring有两个核心 IOC和AOP 1 IOC 控制反转 xff0c 把创建对象过程交给Spring进行
  • 2 计算机网络性能指标

    文章目录 速率带宽吞吐量时延时延带宽积往返时间网络利用率 速率 连接在计算机网络上的主机在数字信道上传送数据位数的速率 xff0c 也称为data rate或bit rate 单位是b s kb s Mb s Gb s 比特 xff08 b
  • Spring之IOC概念

    一 什么是IOC 1 IOC就是控制反转 xff0c 把对象创建和对象之间的调用过程交给Spring进行管理 2 使用IOC目的 之前我们创建对象的方式都是用new的方式创建 xff0c 这个方式有个缺点 xff0c 被创建对象的类的位置一
  • Spring之IOC操作Bena-XML配置文件

    一 什么是操作Bena管理 Bean管理指的是两个操作 1 Spring创建对象 2 Spring注入属性 二 Bean管理操作xml配置文件方式实现 1 基于xml方式创建对象 创建对象的时候默认执行无参构造方法 例 xff1a lt X
  • Spring之IOC操作Bena-XML注入其他类型属性值

    一 字面量 1 注入空值 lt 利用null标签将name属性设置为空值 gt lt property name 61 34 name 34 gt lt null gt lt property gt 2 注入属性包含特殊符号 方法一 xff
  • Spring之AOP

    目录 1 AOP基本概念 2 AOP底层原理 3 AOP相关术语 4 Spring中AOP操作 5 AOP操作 AOP注解 6 AOP操作 AOPXML配置 1 AOP基本概念 1 面向切片 xff08 方面 xff09 编程 xff0c
  • MyBatis-逆向工程

    正向工程 xff1a 先创建Java实体类 xff0c 由框架负责根据实体类生成数据库表 Hibernate是支持正向工程 的 逆向工程 xff1a 先创建数据库表 xff0c 由框架负责根据数据库表 xff0c 反向生成如下资源 xff1
  • Spring Boot-配置文件yaml

    1 配置文件类型 properties xff1a key 61 valueyaml xff1a key xff1a 空格 value 2 基本语法 key value xff1b kv之间有空格大小写敏感使用缩进表示层级关系缩进不允许使用
  • JDK、JRE、JVM

    JDK与JRE JDK gt J ava D evelopment K it Java开发工具包 JDK是提供给Java开发人员使用的 xff0c 其中包含了Java的开发工具 xff0c 也包括了JRE 开发工具 xff1a 编译工具 j
  • Redis-概述

    1 什么是Redis xff1f Redis Re mote Di ctionary S erver 远程字典服务器 xff0c 是开源的 xff0c 使用c语言编写的 xff0c 是基于内存的高性能的Key Value数据库 作者 ant
  • HTML点击刷新验证码

    HTML点击刷新验证码 之前的代码 span class token tag span class token tag span class token punctuation lt span div span span class tok
  • 基于java的小区物业报修管理系统

    本毕业设计课题是基于JAVAEE的小区物业报修管理系统 xff0c 以计算机为操作工具 xff0c MyEclipse为开发平台 mysql为后台数据库 系统开发将采用MVC模式 xff0c 实现对物业报修管理和报修服务评价管理等功能 xf
  • 3 物理层 数据通信基础知识 奈氏准则与香农定理 物理层传输介质 信道复用技术

    文章目录 1 物理层基本概念2 数据通信的基础知识2 1 典型的数据通信系统模型2 2 与通信相关的几个术语2 3 有关信道的几个概念2 4 基带 baseband 信号和带通 band pass 信号2 5 几种最基本的调制方法2 6 网
  • Android Studio 关于BottomNavigationView 无法预览视图的三种常规解决方法

    最近在使用底部导航栏 BottomNavigationView 时 xff0c 应用能正常运行 xff0c 但右侧Split Design无法显示预览视图 xff0c 很不方便 xff0c 查阅大量资料后 xff0c 得到了两种主流解决方案
  • ubuntu分辨率异常问题

    当ubuntu分辨率出现不正常情况时 xff0c 可能有两种现象 xff1a 当出现整体图标都偏大或者偏小的问题时 xff0c 可能是由于分辨率设置异常 如果存在响应的分辨率进行设置即可 xff0c 如果不存在则使用xrandr进行添加 x
  • VR版“半条命”大火,VR游戏迎来消费级市场的春天?

    彼之砒霜 xff0c 汝之蜜糖 2020年的艰难开局 xff0c 在让众多行业陷入困顿之际 xff0c 却让游戏业迎来了一场流量的盛宴 除了日进斗金的王者 吃鸡 xff0c 还有火爆朋友圈的动森 xff0c 一款3A级VR游戏 Half L
  • 读懂海尔智家大脑:深度体验的本质是深度生活

    了解科技行业的读者 xff0c 应该都对 大脑 这个名词不陌生 黑灯工厂 里指挥生产的 工业大脑 xff0c 繁忙机场里运筹帷幄的 航空大脑 xff0c 还有智慧城市建设的灵魂 城市大脑 如果家也有一颗总揽全局的大脑 xff0c 生活会发生
  • ubuntu 安装包报:下列软件包有未满足的依赖关系:

    root 64 ubuntu usr src linux 5 0 1 apt install zlib1g dev 正在读取软件包列表 完成 正在分析软件包的依赖关系树 正在读取状态信息 完成 有一些软件包无法被安装 如果您用的是 unst
  • vSphere虚拟化之ESXi安装及部署

    vSphere虚拟化之ESXi安装及部署 1 安装ESXi2 步骤 vClient的安装及连接3 使用VMware VSphere Client远程安装虚拟机 1 安装ESXi 安装环境 xff1a 用VMware安装ESXi 6 0一台虚
  • Flutter 学习之DIO封装

    简介 xff1a 需要导入的库 dio 3 0 9 json serializable 3 3 0 dio cookie manager 1 0 0 dio http cache 0 2 6 介绍 xff1a 在自己的这个封装中集成了 显示