热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Flutter对Dio的封装以及注意事项

Flutter对Dio的封装以及注意事项-基本使用能够的两种方式回调使用方式NetUtil.instance.fetchUser(UserSettingService.appM

基本使用能够的两种方式

回调使用方式
NetUtil.instance.fetchUser(UserSettingService.appMenu, successCallback: (res) {
  Log.i("resPayData === $res");
  var result = AppMenuResponse.fromJson(res);
}, errorTypeCallback: (value) {
  Log.i("resPayData === $value");
});
同步使用方式
var resPayCode =
    await NetUtil.instance.fetchUser(UserSettingService.payCode);
Log.i("resPayData === $resPayCode");
var payCodeRespOnse= PayCodeResponse.fromJson(resPayCode);
_updateUi(payCodeResponse);

代码实现

import 'dart:convert';
import 'dart:io';

import 'package:bilibili_flutter/common/constant/bl_constant.dart';
import 'package:bilibili_flutter/common/log/bl_log.dart';
import 'package:dio/adapter.dart';
import 'package:dio/dio.dart';

import 'dart:convert' as convert;

typedef ErrorTypeCallback = void Function();
typedef SuccessCallback = void Function(dynamic);

class NetUtil {
  NetUtil._private();

  factory NetUtil() {
    return _instance ??= NetUtil._private();
  }

  static NetUtil? _instance;

  static NetUtil _getInstance() {
    _instance ??= NetUtil._private();
    return _instance!;
  }

  static get instance => _getInstance();

  getCurrentTimeMillis() {
    return DateTime.now().millisecondsSinceEpoch;
  }

  final _dio = Dio(BaseOptions(
    connectTimeout: 5000,
    receiveTimeout: 5000,
  ));

  Future fetchUser(
    String path, {
    Map paramData = const {},
    SuccessCallback? successCallback,
    ErrorTypeCallback? errorTypeCallback,
  }) async {
    return await fetchData("${GlobalConstant.host}$path",
        param: paramData,
        successCallback: successCallback,
        errorTypeCallback: errorTypeCallback);
  }

  Future fetchData(
    String url, {
    Map param = const {},
    SuccessCallback? successCallback,
    ErrorTypeCallback? errorTypeCallback,
  }) async {
    try {
      (_dio.httpClientAdapter as DefaultHttpClientAdapter).OnHttpClientCreate=
          (client) {
        client.badCertificateCallback = (cert, host, port) {
          Log.i("host === $host");
          Log.i("port === $port");
          Log.i("sha1 === ${cert.sha1}");
          Log.i("issuer === ${cert.issuer}");
          Log.i("pem === ${cert.pem}");
          return true;
        };
      };
      Log.i("被调用了一次");
      Log.i("url == $url");
      var jsOnParam= {};
      param.forEach((key, value) {
        jsonParam[key] = value;
      });

      jsonParam["ts"] = getCurrentTimeMillis();

      _dio.interceptors.add(InterceptorsWrapper(onRequest: (options, handler) {
        _dio.lock();
        options.headers.remove("Content-Type");
        var headerParam = {
          "Connection": "true",
          "os": _getPlatformName(),
          "lang": "zh-cn",
          "ENCRYPT": "1",
          "Content-Type": "application/x-www-form-urlencoded"
        };
        // headerParam["token"] = token;
        options.headers.addAll(headerParam);
        _dio.unlock();
        //请求数据前拦截
        handler.next(options);
      }, onResponse: (response, handler) {
        //响应数据拦截
        Log.i("onResponse:x === $response  y ==== $handler");
        handler.next(response); //保证链路关联上,不然请求不会被调用。
      }, onError: (error, handler) {
        //异常数据拦截
        Log.i("onError:x === $error  y ==== $handler");
        handler.next(error);
      }));
      var requestParam = convert.jsonEncode(jsonParam);

      Log.i("请求参数未加密:$requestParam");
      // var encodeParam = aesEncode(requestParam, encryptKey, aesIv);

      // Log.i("请求参数已加密:$encodeParam");
      // var respOnse=
      //     await _dio.post(url, data: "post_data=$encodeParam");
      var respOnse= await _dio.post(url, data: "post_data=");

      if (response.statusCode == 200) {
        Log.i("response statusCode ==  ${response.statusCode}");
        Log.i("response data ==  ${response.data}");
        var resCOntent=response.data ?? "";
            ""; //aesDecode(response.data ?? "", encryptKey, aesIv);
        var resValue = json.decode(resContent);
        successCallback?.call(resValue);
        // Log.i("解密数据:$resContent");
        return resValue;
      } else {
        //TODO 其他异常进行对应提示
        errorTypeCallback?.call();
      }
    } catch (e) {
      Log.i("发送了错误 === $e");
      errorTypeCallback?.call();
    }
  }

  /**
   * 定义私有的获取平台的类型
   */
  String _getPlatformName() {
    if (Platform.isAndroid) {
      return "Android";
    } else if (Platform.isIOS) {
      return "ios";
    } else {
      return "OtherOS";
    }
  }
}

注意事项

1. 添加拦截器后,需要对链进行手动调用,这里猜想应该是用到了设计模式中责任链模式。

_dio.interceptors.add(InterceptorsWrapper(onRequest: (options, handler) {
  _dio.lock();
  options.headers.remove("Content-Type");
  var headerParam = {
    "Connection": "true",
    // "csrf": csrf,
    "os": _getPlatformName(),
    "lang": "zh-cn",
    "ENCRYPT": "1",
    "Content-Type": "application/x-www-form-urlencoded"
  };
  // headerParam["token"] = token;
  options.headers.addAll(headerParam);
  _dio.unlock();///这里需要加锁哦。
  //请求数据前拦截
  handler.next(options);///这里需要手动调用next,不然事件流中的其他注册事件不会执行。
}, onResponse: (response, handler) {
  //响应数据拦截
  Log.i("onResponse:x === $response  y ==== $handler");
  handler.next(response); //保证链路关联上,不然请求不会被调用。
}, onError: (error, handler) {
  //异常数据拦截
  Log.i("onError:x === $error  y ==== $handler");
  handler.next(error);///这里需要手动调用next,不然事件流中的其他注册事件不会执行。
}));
2. 对https证书校验进行验证
(_dio.httpClientAdapter as DefaultHttpClientAdapter).OnHttpClientCreate=
    (client) {
  client.badCertificateCallback = (cert, host, port) {
    Log.i("host === $host");
    Log.i("port === $port");
    Log.i("sha1 === ${cert.sha1}");
    Log.i("issuer === ${cert.issuer}");
    Log.i("pem === ${cert.pem}");
    return true;///这里如果发挥false的话,那么请求将会终端。
  };
};

源码地址

https://github.com/HaiYangCode/BilibiliFlutter/blob/main/lib/common/net/bl_net.dart


推荐阅读
  • PHP中的单例模式与静态变量的区别及使用方法
    本文介绍了PHP中的单例模式与静态变量的区别及使用方法。在PHP中,静态变量的存活周期仅仅是每次PHP的会话周期,与Java、C++不同。静态变量在PHP中的作用域仅限于当前文件内,在函数或类中可以传递变量。本文还通过示例代码解释了静态变量在函数和类中的使用方法,并说明了静态变量的生命周期与结构体的生命周期相关联。同时,本文还介绍了静态变量在类中的使用方法,并通过示例代码展示了如何在类中使用静态变量。 ... [详细]
  • 本文讨论了在openwrt-17.01版本中,mt7628设备上初始化启动时eth0的mac地址总是随机生成的问题。每次随机生成的eth0的mac地址都会写到/sys/class/net/eth0/address目录下,而openwrt-17.01原版的SDK会根据随机生成的eth0的mac地址再生成eth0.1、eth0.2等,生成后的mac地址会保存在/etc/config/network下。 ... [详细]
  • 本文介绍了RxJava在Android开发中的广泛应用以及其在事件总线(Event Bus)实现中的使用方法。RxJava是一种基于观察者模式的异步java库,可以提高开发效率、降低维护成本。通过RxJava,开发者可以实现事件的异步处理和链式操作。对于已经具备RxJava基础的开发者来说,本文将详细介绍如何利用RxJava实现事件总线,并提供了使用建议。 ... [详细]
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ... [详细]
  • 本文介绍了如何使用Express App提供静态文件,同时提到了一些不需要使用的文件,如package.json和/.ssh/known_hosts,并解释了为什么app.get('*')无法捕获所有请求以及为什么app.use(express.static(__dirname))可能会提供不需要的文件。 ... [详细]
  • Java自带的观察者模式及实现方法详解
    本文介绍了Java自带的观察者模式,包括Observer和Observable对象的定义和使用方法。通过添加观察者和设置内部标志位,当被观察者中的事件发生变化时,通知观察者对象并执行相应的操作。实现观察者模式非常简单,只需继承Observable类和实现Observer接口即可。详情请参考Java官方api文档。 ... [详细]
  • React项目中运用React技巧解决实际问题的总结
    本文总结了在React项目中如何运用React技巧解决一些实际问题,包括取消请求和页面卸载的关联,利用useEffect和AbortController等技术实现请求的取消。文章中的代码是简化后的例子,但思想是相通的。 ... [详细]
  • 本文介绍了在MFC下利用C++和MFC的特性动态创建窗口的方法,包括继承现有的MFC类并加以改造、插入工具栏和状态栏对象的声明等。同时还提到了窗口销毁的处理方法。本文详细介绍了实现方法并给出了相关注意事项。 ... [详细]
  • 本文介绍了Java中Currency类的getInstance()方法,该方法用于检索给定货币代码的该货币的实例。文章详细解释了方法的语法、参数、返回值和异常,并提供了一个示例程序来说明该方法的工作原理。 ... [详细]
  • 用Vue实现的Demo商品管理效果图及实现代码
    本文介绍了一个使用Vue实现的Demo商品管理的效果图及实现代码。 ... [详细]
  • express工程中的json调用方法
    本文介绍了在express工程中如何调用json数据,包括建立app.js文件、创建数据接口以及获取全部数据和typeid为1的数据的方法。 ... [详细]
  • 本文介绍了GTK+中的GObject对象系统,该系统是基于GLib和C语言完成的面向对象的框架,提供了灵活、可扩展且易于映射到其他语言的特性。其中最重要的是GType,它是GLib运行时类型认证和管理系统的基础,通过注册和管理基本数据类型、用户定义对象和界面类型来实现对象的继承。文章详细解释了GObject系统中对象的三个部分:唯一的ID标识、类结构和实例结构。 ... [详细]
  • 本文介绍了Java后台Jsonp处理方法及其应用场景。首先解释了Jsonp是一个非官方的协议,它允许在服务器端通过Script tags返回至客户端,并通过javascript callback的形式实现跨域访问。然后介绍了JSON系统开发方法,它是一种面向数据结构的分析和设计方法,以活动为中心,将一连串的活动顺序组合成一个完整的工作进程。接着给出了一个客户端示例代码,使用了jQuery的ajax方法请求一个Jsonp数据。 ... [详细]
author-avatar
Oo输不掉的气质
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有