Flutter:网络请求 Dio简单封装及请求实例和注意问题

flutter中网络请求一般使用 Dio 库,下面我就来基于Dio库做一下简单封装和使用实例以及遇到的问题。

具体请去官网了解: https://pub.dev/packages/dio

首先在项目的 pubspec.yaml文件中  引入相关库:

  # 网络请求
  dio: ^3.0.10
  # cookie 管理
  dio_cookie_manager: ^1.0.0
  #  获取文件目录插件
  path_provider: ^1.6.24
  # app权限
  permission_handler: ^5.0.1

Dio是一个强大的Dart Http请求库,支持Restful API、FormData、拦截器、请求取消、Cookie管理、文件上传/下载、超时、自定义适配器等,具体可以官网查看。

下面我写了个简单的封装类,由于刚开始接触,只简单写了get/post使用:

import 'dart:convert';

import 'package:common_utils/common_utils.dart';
import 'package:cookie_jar/cookie_jar.dart';
import 'package:dio/dio.dart';
import 'PrivateCookieManager.dart';

/*
 * author  Min
 * time    2020/12/26
 * desc    网络请求dio封装
 */
class HttpGo {

  static HttpGo instance;
  static Dio dio;

  static HttpGo getInstance() {
    if (instance == null) {
      dio = Dio();
      instance = HttpGo();
      instance.init();
    }
    return instance;
  }

  void init() async{
    //设置options
    BaseOptions options = new BaseOptions();
    //设置 header--可选--存放一些公共的请求头信息
    Map<String, dynamic> headers = new Map();
    options.headers = headers;
    //设置 content-type--可选
    options.contentType = "application/x-www-form-urlencoded";
    //超时设置--可选
    options.connectTimeout = 5000;
    options.receiveTimeout = 5000;
    options.sendTimeout = 5000;
    //设置 baseurl--可选
    options.baseUrl = "http://apis.juhe.cn";
    dio.options = options;

    //cookie管理--可选
    //cookie管理--获取目录需要引入path_provider库
    Directory appDocDir = await getApplicationDocumentsDirectory();
    String appDocPath = appDocDir.path;
    var cookieJar = PersistCookieJar(dir: appDocPath + "/.cookies/");
    dio.interceptors.add(PrivateCookieManager(cookieJar));

    //添加拦截器--可选
    dio.interceptors
        .add(InterceptorsWrapper(onRequest: (RequestOptions options) {
      return options;
    }, onResponse: (Response response) {
      return response;
    }, onError: (DioError e) {
      return e;
    }));

    //开启请求日志--可选---要放在其他所有之后才会生效
    dio.interceptors.add(LogInterceptor(responseBody: true, requestBody: true));
  }

  /*
   * get请求
   */
  Future<dynamic> get(String url, {Map<String, dynamic> params}) async {
    Response response;
    try {
      response = await dio.get(url, queryParameters: params);
      LogUtil.v(response);
    } catch (e) {
      formatError(e);
    }
    return response.data;
  }

  /*
   * post请求
   */
  Future<dynamic> post(String url, {Map<String, dynamic> params}) async {
    Response response;
    try {
      response = await dio.post(url, data: params);
      LogUtil.v(response);
    } catch (e) {
      formatError(e);
    }
    return response.data;
  }

  /*
  * error统一处理
  */
  void formatError(DioError e) {
    if (e.type == DioErrorType.CONNECT_TIMEOUT) {
      LogUtil.v("连接超时");
    } else if (e.type == DioErrorType.SEND_TIMEOUT) {
      LogUtil.v("请求超时");
    } else if (e.type == DioErrorType.RECEIVE_TIMEOUT) {
      LogUtil.v("响应超时");
    } else if (e.type == DioErrorType.RESPONSE) {
      LogUtil.v("出现异常");
    } else if (e.type == DioErrorType.CANCEL) {
      LogUtil.v("请求取消");
    } else {
      LogUtil.v("未知错误");
    }
  }
}

下面再测试下:

/*
 * 请求实例
 */
void main() {
  //初始化log工具
  LogUtil.init(isDebug: true);

  //查询手机号码归属地--(来自聚合数据)
  Map<String, dynamic> param = {
    "key": "----这里输入key---",
    "phone": "----这里输入手机号---",
    "dtype": "json"
  };

  //get方式
  var result = HttpGo.getInstance().get("/mobile/get", params: param);

  //post方式
  var result2 = HttpGo.getInstance().post("/mobile/get", params: param);
}

好了,一个简单的网络请求到此结束。下面我们来说一下注意事项。

1.关于cookie :这里我写下了CookieManager,因为cookie包含了一些特殊字符,如:[];()@,?=等,会导致解析报错,并抛出以下异常,文件及详情可去看我的另一篇博文 :https://blog.csdn.net/zhangyiminsunshine/article/details/111735229

2.关于post请求中提交参数的问题

dio中如果设置了 BaseOptions ,baseoptions的queryParameters 会让之后的  queryParameters失效,导致post参数提交不上去

应使用: 

 response = await dio.post(url, data: params);

3.app中使用需要获取网络请求权限,使用cookie需要获取读写权限

在Android的AndroidManifest.xml文件下添加权限

<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

pubspec.yaml中加入 permission_handler: ^5.0.1

然后在合适位置请求权限

Future<void> requestBasePermission() async {
    Map<Permission, PermissionStatus> statuses = await [
        Permission.storage,
    ].request();

  }

然后就可以使用网络请求了。关于权限的后续操作请看permission_handler的介绍。

 

本文为原创文章,未经本人同意,不得转载。

 

 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值