美文网首页
Flutter 开发 之 Dio 封装

Flutter 开发 之 Dio 封装

作者: 青青雉 | 来源:发表于2020-05-14 17:20 被阅读0次

    简介:

    需要导入的库

    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写的文章。

    相关文章

      网友评论

          本文标题:Flutter 开发 之 Dio 封装

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