[Flutter3] 记录Dio的简单封装(一)

news2025/1/16 8:16:40

文章目录

  • 效果
  • 使用
  • ResponseEntity类
  • DioManager封装
    • _onResponse / _onDioException 的设计
    • Response的处理
    • catch处理

效果

请求成功/失败/异常的日志输出效果
成功:
在这里插入图片描述
失败:500
在这里插入图片描述
失败:404
在这里插入图片描述
网络异常:
在这里插入图片描述

使用

举个使用的例子, 在调用 DioManager的时候, 直接通过返回值的状态, 来处理各个情况,不用在 try{}catch{}里面各写一遍处理逻辑,

比如上图,就是直接调用的封装的API

      ResponseEntity res = await DioManager().requestGet(HttpApi.user_record, param: {
        "openid": "okqbz5K-4UoymmukFtxyQAyImKm0",
        "uid": "88030",
        "subject": '20',
        "unionid": "ofJJv6M45ChFhuUZyVaLXwt07M4g",
      });
      res.toLog();

直接同步获取了请求的结果,通过 ResponseEntity 来处理本次请求的各项情况(如上4图)

ResponseEntity类

提供了 泛型T的data属性,
提供了 tag, 用于处理请求的不同情况
提供了 toString/ toLog函数 , 用于查看请求/返回/状态码/请求参数等


class ResponseEntity<T> {
  /// 常规的response.data的返回字段
  late String? msg;
  late int? code;
  T? data;

  /// response.data中,自定以追加的一些字段(方便日志查看)
  late int? tag; // 业务tag  0=>通信OK+业务未跑通 1=>通信OK+业务跑通  2=>通信失败(各类原因...) 9=>解析/socket等异常
  late String? method; // 请求的 method
  late String? baseUrl; // 请求的host地址 - 方便打印日子产看环境
  late String? path; // 请求地址
  late String? desc; // 自定义的报文描述-便于判断请求情况
  late Map<String, dynamic>? queryParameters; // 请求的参数

  ResponseEntity(
      this.code, this.msg, this.data, this.tag, this.method, this.baseUrl, this.path, this.desc, this.queryParameters);

  ResponseEntity.initFromJson(Map<String, dynamic> jsonMap) {
    code = jsonMap.containsKey(ConstantUtil.code) ? jsonMap[ConstantUtil.code] as int? : 0;
    msg = jsonMap.containsKey(ConstantUtil.msg) ? jsonMap[ConstantUtil.msg] as String? : "";
    // 存在data
    if (jsonMap.containsKey(ConstantUtil.data)) {
      data = jsonMap[ConstantUtil.data] as T;
    }

    /// response自定以追加的一些字段处理
    tag = jsonMap.containsKey(ConstantUtil.tag) ? jsonMap[ConstantUtil.tag] : 9;
    method = jsonMap.containsKey(ConstantUtil.method) ? jsonMap[ConstantUtil.method] : "";
    baseUrl = jsonMap.containsKey(ConstantUtil.baseUrl) ? jsonMap[ConstantUtil.baseUrl] : "";
    path = jsonMap.containsKey(ConstantUtil.path) ? jsonMap[ConstantUtil.path] : "";
    queryParameters = jsonMap.containsKey(ConstantUtil.queryParameters) ? jsonMap[ConstantUtil.queryParameters] : null;
    desc = jsonMap.containsKey(ConstantUtil.desc) ? jsonMap[ConstantUtil.desc] : "";
  }

  /// 手动重写toString 方法,方便查看日志
  
  String toString() {
    var _code = "code:$code\n";
    var _msg = "msg:$msg\n";
    var _data = json.encode(data).toString();
    var _dataString = "data:$_data\n";
    var _tag = "tag:$tag\n";
    var _method = "method:$method\n";
    var _baseUrl = "baseUrl:$baseUrl\n";
    var _path = "path:$path\n";
    var _desc = "path:$desc\n";
    var _queryParameters = jsonEncode(queryParameters);
    var _queryParametersString = "queryParameters:$_queryParameters\n";

    return _code + _msg + _dataString + _tag + _method + _baseUrl + _path + _desc + _queryParametersString;
  }

  /// 提供自带的打印函数
  void toLog() {
    LoggerUtil().d(toString());
  }
}

DioManager封装

对DioManager进行单例模式处理

  /// dio管理类的单例的实现 --------------------------------------------------
  // 定义私有管理对象 _singleton
  static final DioManager _singleton = DioManager._();

  // 私有对象构造实现
  DioManager._() {
    // dio初始化 - 配置全局options - 具体事项先省略
  }

  // 声明并完成初始化的私有变量(_singleton),
  // 通过 DioManager的工厂函数(factory关键字) ,进行单例模式返回
  factory DioManager() => _singleton;

提供_request通用方法

 /// request 通用处理函数 -----------------------------------------------------------
  /// get 对应的是 queryParam
  /// post 对应的是 data
  /// 通过 对 try/catch 的处理, 均异步返回有效的 BaseResponseEntity<T> 实例,
  /// 外部调用时候,仅获取数据是, 可以不必包裹 try/catch,
  Future<ResponseEntity<T>> _request<T>(
    String method,
    String apiPath, {
    Map<String, dynamic>? param,
    CancelToken? cancelToken,
    Options? options,
  }) async {
    try {
      // 通用请求
      Response<dynamic> response = await _dio.request(apiPath,
          data: param, queryParameters: param, cancelToken: cancelToken, options: _loadOptions(method, options));
      // 通过 _onResponse()函数转换response
      // 自定义返回的data内容, 除了原有的 code/msg/data信息, 新增desc/tag等返回数据
      response = _onResponse(response);
      return ResponseEntity<T>.initFromJson(response.data);
    } on DioException catch (err) {
      // 通过对DioException的解析,返回自定义的BaseResponseEntity实例
      return _onDioException(err) as ResponseEntity<T>;
    }

  }

_onResponse / _onDioException 的设计

根据Request的情况, 把交互场景分为了四类

1&2: statusCode == 200 , 再区分业务code是否OK
3: statusCode !==200, 可能是 404 /500 等情况
4: 断网等异常情况

其中 1&2&3, 都是通过_onResponse处理
4通过_onDioException处理, 这里的catch不再直接抛出, 用ResponseEntity来统一做返回格式处理
(DioException)

Response的处理

class ResponseEntity<T> {
  /// 常规的response.data的返回字段
  late String? msg;
  late int? code;
  T? data;

  /// response.data中,自定以追加的一些字段(方便日志查看)
  late int? tag; // 业务tag  0=>通信OK+业务未跑通 1=>通信OK+业务跑通  2=>通信失败(各类原因...) 9=>解析/socket等异常
  late String? method; // 请求的 method
  late String? baseUrl; // 请求的host地址 - 方便打印日子产看环境
  late String? path; // 请求地址
  late String? desc; // 自定义的报文描述-便于判断请求情况
  late Map<String, dynamic>? queryParameters; // 请求的参数

  ResponseEntity(
      this.code, this.msg, this.data, this.tag, this.method, this.baseUrl, this.path, this.desc, this.queryParameters);

  ResponseEntity.initFromJson(Map<String, dynamic> jsonMap) {
    code = jsonMap.containsKey(ConstantUtil.code) ? jsonMap[ConstantUtil.code] as int? : 0;
    msg = jsonMap.containsKey(ConstantUtil.msg) ? jsonMap[ConstantUtil.msg] as String? : "";
    // 存在data
    if (jsonMap.containsKey(ConstantUtil.data)) {
      data = jsonMap[ConstantUtil.data] as T;
    }

    /// response自定以追加的一些字段处理
    tag = jsonMap.containsKey(ConstantUtil.tag) ? jsonMap[ConstantUtil.tag] : 9;
    method = jsonMap.containsKey(ConstantUtil.method) ? jsonMap[ConstantUtil.method] : "";
    baseUrl = jsonMap.containsKey(ConstantUtil.baseUrl) ? jsonMap[ConstantUtil.baseUrl] : "";
    path = jsonMap.containsKey(ConstantUtil.path) ? jsonMap[ConstantUtil.path] : "";
    queryParameters = jsonMap.containsKey(ConstantUtil.queryParameters) ? jsonMap[ConstantUtil.queryParameters] : null;
    desc = jsonMap.containsKey(ConstantUtil.desc) ? jsonMap[ConstantUtil.desc] : "";
  }

  /// 手动重写toString 方法,方便查看日志
  
  String toString() {
    var _code = "code:$code\n";
    var _msg = "msg:$msg\n";
    var _data = json.encode(data).toString();
    var _dataString = "data:$_data\n";
    var _tag = "tag:$tag\n";
    var _method = "method:$method\n";
    var _baseUrl = "baseUrl:$baseUrl\n";
    var _path = "path:$path\n";
    var _desc = "path:$desc\n";
    var _queryParameters = jsonEncode(queryParameters);
    var _queryParametersString = "queryParameters:$_queryParameters\n";

    return _code + _msg + _dataString + _tag + _method + _baseUrl + _path + _desc + _queryParametersString;
  }

  /// 提供自带的打印函数
  void toLog() {
    LoggerUtil().d(toString());
  }
}

catch处理

  /// 对 DioException进行解析,基本覆盖大部分错误类型了
  ResponseEntity _onDioException(DioException err) {
    var errType = err.type;
    var path = err.requestOptions.path;
    var data = err.requestOptions.data;
    var queryParameters = err.requestOptions.queryParameters;
    var baseUrl = err.requestOptions.baseUrl;
    var method = err.requestOptions.method;

    ResponseEntity baseResponseEntity = ResponseEntity(0, "", data, 9, method, baseUrl, path, "", queryParameters);

    ///连接超时
    if (errType == DioExceptionType.connectionTimeout) {
      baseResponseEntity.msg = "连接超时";
      baseResponseEntity.desc = "连接超时";
    }

    ///发送超时
    if (errType == DioExceptionType.sendTimeout) {
      baseResponseEntity.msg = "发送超时";
      baseResponseEntity.desc = "发送超时";
    }

    ///接收超时
    if (errType == DioExceptionType.receiveTimeout) {
      baseResponseEntity.msg = "接收超时";
      baseResponseEntity.desc = "接收超时";
    }

    ///证书损坏
    if (errType == DioExceptionType.badCertificate) {
      baseResponseEntity.msg = "证书损坏";
      baseResponseEntity.desc = "证书损坏";
    }

    ///返回内容问题
    if (errType == DioExceptionType.badResponse) {
      baseResponseEntity.msg = "返回内容问题";
      baseResponseEntity.desc = "返回内容问题";
    }

    ///请求取消
    if (errType == DioExceptionType.cancel) {
      baseResponseEntity.msg = "请求取消";
      baseResponseEntity.desc = "请求取消";
    }

    ///连接错误-无网络
    if (errType == DioExceptionType.connectionError) {
      baseResponseEntity.msg = "连接错误-无网络";
      baseResponseEntity.desc = "连接错误-无网络";
    }

    ///未知错误
    if (errType == DioExceptionType.unknown) {
      baseResponseEntity.msg = "未知错误";
      baseResponseEntity.desc = "未知错误";
    }
    return baseResponseEntity;
  }

针对ResponseEntity中, T? data 的处理, 稍后补上, 先走通请求…

— 数据转模型看这个
[Flutter3] Json转dart模型举例

对于泛型T的处理, 直接把 json转model的model类型传入泛型就可获取数据

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1623138.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

世强硬创获昕感科技授权代理,SiC MOSFET实现超低导通电阻

近日&#xff0c;世强先进&#xff08;深圳&#xff09;科技股份有限公司&#xff08;下称“世强先进”&#xff09;获北京昕感科技有限责任公司&#xff08;下称“昕感科技”&#xff0c;英文名&#xff1a;NEXIC&#xff09;授权代理&#xff0c;为光伏、储能、电网、新能源汽…

【芯片科普】运算放大器用作比较器的注意事项

运算放大器和比较器 比较器和运算放大器电气符号非常相像&#xff0c;都是有反相、同相两个输入端和一个输出端的器件&#xff0c;输出端的输出电压范围一般在供电的轨到轨之间&#xff1b;同时比较器和运算放大器都具有低偏置电压、高增益和高共模抑制比的特点。 图1 运算放…

第十五届蓝桥杯省赛第二场C/C++B组F题【狡兔k窟】题解(AC)

题意分析 有一个 n n n 个点&#xff0c; n − 1 n-1 n−1 条边的无向图&#xff0c;边权均为 1 1 1。 每个点隶属于一个集合&#xff0c;同一个集合的点可以互相传送。 给定 m m m 个询问&#xff0c;求 x , y x, y x,y 的最短距离。 最短路解法 步骤&#xff1a; 建…

4.7 海思SS928开发 - uboot开发 - 自定义分区以及启动方案

4.7 uboot开发 - 自定义分区以及启动方案 ss928 出厂默认的启动方式以及 emmc 默认的分区&#xff0c;不符合需求&#xff0c;考虑自己做一个分区方案以及启动方案。 分区方案 分区表如下&#xff1a; 分区文件系统分区说明fastboot-存放 bootloaderubootenv-存储 uboot 环境…

jenkins修改全局安全配置之后登录错误

教训&#xff08;流泪&#xff09; 事情是这样的&#xff0c;第一次我需要用单点登录集成jenkins&#xff0c;jenkins可以通过插件的方式支持cas协议&#xff0c;我当时也不很懂&#xff0c;经过我学网上的一顿乱配置&#xff0c;jenkis上不去了&#xff0c;虽然这是公司本地环…

Nginx 配置 SSL(HTTPS)详解

Nginx作为一款高性能的HTTP和反向代理服务器&#xff0c;自然支持SSL/TLS加密通信。本文将详细介绍如何在Nginx中配置SSL&#xff0c;实现HTTPS的访问。 随着互联网安全性的日益重要&#xff0c;HTTPS协议逐渐成为网站加密通信的标配。Nginx作为一款高性能的HTTP和反向代理服务…

C语言----枚举

当我们看过了结构体和联合体&#xff0c;那么我们接下来就将学习枚举。这也许对大家又是一个新的知识点。大家不要急&#xff0c;我来给大家简单的总结一下。先看名字&#xff0c;枚举就是一个个列举。这样大家应该比较熟悉吧。如一周有七天。这个肯定要分开列举出来吧&#xf…

LLMs——扩展数据受限的语言模型解决方案

概述 在自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;大型语言模型的发展一直是研究的热点。这些模型通过增加参数数量和训练数据量来提升性能&#xff0c;但这种增长趋势是否会有一个极限&#xff1f;实际上&#xff0c;研究者们已经注意到&#xff0c;为了有效地…

03-JAVA设计模式-观察者模式

观察者模式 什么是观察者模式 Java中的观察者模式是一种常见的设计模式&#xff0c;它允许对象&#xff08;观察者&#xff09;订阅另一个对象&#xff08;被观察者&#xff09;的状态变化&#xff0c;并在状态变化时自动得到通知。 核心&#xff1a; 观察者模式主要用于1&a…

Python 基础 (Pandas):Pandas 入门

1. 官方文档 API reference — pandas 2.2.2 documentation 2. 准备知识&#xff1a;Pandas 数据结构 Series & DataFrame 2.1 Series 2.1.1 创建 Series 类型数据 一个 Series 对象包含两部分&#xff1a;值序列、标识符序列。可通过 .values (返回 NumPy ndarry 类型…

Swift - 基础语法

文章目录 Swift - 基础语法1. 常量1.1 只能赋值1次1.2 它的值不要求在编译时期确定&#xff0c;但使用之前必须赋值1次1.3 常量、变量在初始化之前&#xff0c;都不能使用 2. 标识符3. 常用数据类型4. 字面量4.1 布尔4.2 字符串4.3 整数4.4 浮点数4.5 数组4.6 字典 5. 类型转换…

【C++】string类的增删改查模拟实现(图例超详细解析!!!)

目录 一、前言 二、string类的模拟实现 ✨前情提要 ✨Member functions —— 成员函数 ⚡构造函数 ⚡拷贝构造函数 ⚡赋值运算符重载 ⚡析构函数 ✨Element access —— 元素访问 ⚡operator[ ] ⚡Iterator —— 迭代器 ✨Capacity —— 容量 ⚡size ⚡capacity ⚡clea…

记录一个Maxwell采集MySQL数据时报安全证书时间不通过的问题

【背景描述】 我的zk&#xff0c;kafka和Maxwell都正常启动了 此时我需要用Maxwell将MySQL的一张表user_info将其全量同步到kafka当中时发生报错&#xff0c;命令如下&#xff1a; [atguiguhadoop102 datas]$ /opt/module/maxwell/bin/maxwell-bootstrap --database gmall --…

Mongodb语法使用说明(含详细示例)

点击下载《Mongodb语法使用说明&#xff08;含详细示例&#xff09;》 1. 前言 MongoDB是一款高性能、开源、面向文档的NoSQL数据库&#xff0c;它使用类似JSON的BSON格式存储数据&#xff0c;提供了灵活的数据模型和强大的查询功能。本文将详细介绍MongoDB数据库的基本增删改…

机器学习-期末复习

本文的内容按照作者的课程考试要求书写&#xff0c;仅供复习参考。&#x1f337;&#x1f337;&#x1f337;欢迎大家指正&#xff01; 机器学习是一种人工智能&#xff08;AI&#xff09;的分支领域&#xff0c;它致力于开发能够通过数据学习和改进的算法和模型。简而言之&…

深入学习Linux中的“文件系统与日志分析”

目录 1.文件系统的组成 1.1inode和block 1.2inode的内容 1.3inode的号码 ​1.4文件存储小结 ​1.5inode大小 1.6inode的特殊作用 2. 链接文件 3.文件恢复 3.1EXT类型文件恢复 3.2磁盘有空间&#xff0c;但是仍然无法写入新文件 3.3恢复XFS类型的文件 3.3.1xfsdump…

面试:JVM内存结构

一、Java代码的运行步骤 一段Java代码先会被反编译为Java字节码&#xff0c;当执行java命令时&#xff0c;JVM虚拟机会被创建出来&#xff0c;并会创建一个main主线程来执行主方法。 二、JVM的内存结构有哪些&#xff1f; 1、方法区&#xff1a;&#xff08;线程共享&#xff…

实验五 Spark SQL编程初级实践

Spark SQL编程初级实践 Spark SQL基本操作 将下列JSON格式数据复制到Linux系统中&#xff0c;并保存命名为employee.json。 { "id":1 , "name":" Ella" , "age":36 } { "id":2, "name":"Bob","a…

婴儿专用洗衣机有必要吗?四大宝藏婴儿洗衣机测评对比

对于有了宝宝的家庭来说&#xff0c;洗衣成为了一项重要的家务事。大家都知道&#xff0c;宝宝的皮肤比较娇嫩&#xff0c;容易受到各种细菌、病毒的侵扰。所以&#xff0c;宝宝的衣物应该与大人的分开洗。婴儿洗衣机作为一种专门为婴幼儿家庭设计的洗衣机&#xff0c;其具有除…

Ubuntu 20.04.6下载、安装

一、下载 下载地址&#xff1a;https://cn.ubuntu.com/download 下载版本&#xff1a;ubuntu-20.04.6-desktop-amd64.iso 二、安装 参考博客&#xff1a; https://blog.csdn.net/lhl_blog/article/details/123406322 https://www.cnblogs.com/fieldtianye/p/17879840.html…