Flutter网络通信-封装Dio

前言

dio 是一个强大的 Dart HTTP 请求库,支持全局配置、Restful API、FormData、拦截器、 请求取消、Cookie 管理、文件上传/下载、超时以及自定义适配器等。

Dio的pub地址为:dio | Dart package

封装要求

  • 能够使用get、post、put、patch、delete、postForm、postStream请求
  • 能够使用token
  • 能够取消请求
  • 不论网络通信是否成功,返回的格式保持一致

封装步骤

1.添加依赖

dart pub add dio

2.创建一个名称为HttpUtil的工厂函数

class HttpUtil {
  static final HttpUtil _instance = HttpUtil.internal();
  factory HttpUtil() => _instance;
}

在HttpUtil.internal中初始化Dio

  • baseUrl是请求基地址,根据自己的需求转换

  • InterceptorsWrapper中添加了拦截器

  • 不论请求成功与否,返回的data都是DioResponse类型,我们根据DioResponse对数据进行解析

    HttpUtil.internal() {
    // BaseOptions、Options、RequestOptions 都可以配置参数,优先级别依次递增,且可以根据优先级别覆盖参数
    BaseOptions options = BaseOptions(
    //请求基地址
    baseUrl: SERVER_API_URL,

      // baseUrl: storage.read(key: STORAGE_KEY_APIURL) ?? SERVICE_API_BASEURL,
      //连接服务器超时时间
      connectTimeout: const Duration(seconds: 20),
      // 响应流上前后两次接受到数据的间隔
      receiveTimeout: const Duration(seconds: 20),
      // Http请求头.
      headers: {},
    
      /// 请求的Content-Type,默认值是"application/json; charset=utf-8".
      /// 如果您想以"application/x-www-form-urlencoded"格式编码请求数据,
      /// 可以设置此选项为 `Headers.formUrlEncodedContentType`,  这样[Dio]
      /// 就会自动编码请求体.
      contentType: 'application/json; charset=utf-8',
    
      /// [responseType] 表示期望以那种格式(方式)接受响应数据。
      /// 目前 [ResponseType] 接受三种类型 `JSON`, `STREAM`, `PLAIN`.
      ///
      /// 默认值是 `JSON`, 当响应头中content-type为"application/json"时,dio 会自动将响应内容转化为json对象。
      /// 如果想以二进制方式接受响应数据,如下载一个二进制文件,那么可以使用 `STREAM`.
      ///
      /// 如果想以文本(字符串)格式接收响应数据,请使用 `PLAIN`.
      responseType: ResponseType.json,
    );
    dio = Dio(options);
    // CookieJar   Dart 中用于 http 请求的 cookie 管理器,您可以通过它轻松处理复杂的 cookie 策略并持久化 cookie。
    // CookieJar cookieJar = CookieJar();
    // dio.interceptors.add(CookieManager(cookieJar));
    
    // 添加拦截器
    dio.interceptors.add(
      InterceptorsWrapper(
        onRequest: (RequestOptions options, RequestInterceptorHandler handler) {
          /// 如果你想完成请求并返回一些自定义数据,你可以使用 `handler.resolve(response)`。
          ///这样请求将会被终止,上层then会被调用,then中返回的数据将是你的自定义response.
    
          /// 如果你想终止请求并触发一个错误,你可以使用 `handler.reject(error)`。
          /// 这样请求将被中止并触发异常,上层catchError会被调用。
          ///
          return handler.next(options);
        },
        onResponse: (response, handler) {
          // 如果你想终止请求并触发一个错误,你可以使用 `handler.reject(error)`。
          //这样请求将被中止并触发异常,上层catchError会被调用。
          // 请求成功是对数据做基本处理
    
          if (response.statusCode == 200) {
            response.data =
                DioResponse(code: 200, message: "请求成功啦", data: response.data);
          } else {
            response.data = DioResponse(
                code: response.statusCode,
                message: "请求失败啦",
                data: response.data);
          }
          return handler.next(response);
        },
        onError: (e, handler) {
          //停止加载
          // Loading.dismiss();
          print("-=-=-=-onError$e,-----$handler");
    
          EasyLoading.instance.userInteractions = true;
          EasyLoading.dismiss();
          DioResponse? eInfo;
          if ("$e".contains("The request connection took longer")) {
            eInfo = DioResponse(code: -1, message: "连接超时", data: "");
          } else {
            eInfo = createErrorEntity(e);
          }
          onError(eInfo);
          Response response = Response(data: eInfo, requestOptions: RequestOptions());
          return handler.resolve(response); //continue
    
          // 如果你想完成请求并返回一些自定义数据,可以resolve 一个`Response`,如`handler.resolve(response)`。
          // 这样请求将会被终止,上层then会被调用,then中返回的数据将是你的自定义response.
        },
      ),
    );
    

    }

3.定义DioResponse

  • code是请求返回的状态码

  • data是后端返回的数据

    class DioResponse<T> {
    /// 消息(例如成功消息文字/错误消息文字)
    final String message;

    /// 自定义code(可根据内部定义方式)
    final int? code;
    
    /// 接口返回的数据
    final T data;
    
    /// 需要添加更多
    /// .........
    
    DioResponse({
      required this.message,
      required this.data,
      required this.code,
    });
    factory DioResponse.fromJson(Map<String, dynamic> json) => DioResponse(
          code: json["code"],
          message: json["message"],
          data: json["data"],
        );
    Map<String, dynamic> toJson() => {
          "message": message,
          "data": data,
          "code": code,
        };
    

    }

4.对错误请求进行DioResponse处理

//错误信息
  DioResponse createErrorEntity(DioError error) {
    // print('error.type${error.type}');
    var data = error.response?.data;
    print(
        "进入了错误信息:error.type:${error.type},错误的码:¥「${error.response!.statusCode},,data:¥${data}");
    switch (error.type) {
      case DioErrorType.cancel:
        return DioResponse(code: -1, message: "请求取消", data: data);
      case DioErrorType.connectionTimeout:
        return DioResponse(code: -1, message: "连接超时", data: data);
      case DioErrorType.sendTimeout:
        return DioResponse(code: -1, message: "请求超时", data: data);
      case DioErrorType.receiveTimeout:
        return DioResponse(code: -1, message: "响应超时", data: data);
      case DioErrorType.badResponse:
        try {
          print("data:$data");
          int errCode =
              error.response != null ? error.response!.statusCode! : -1;
 
          return DioResponse(
              code: errCode, message: data["message"], data: data);
        } catch (e) {
          return DioResponse(code: -1, message: "badResponse抛出了异常", data: e);
        }
 
      case DioErrorType.unknown:
        {
          try {
            int errCode =
                error.response != null ? error.response!.statusCode! : -1;
 
            switch (errCode) {
              case 400:
                return DioResponse(
                    code: errCode, message: "请求语法错误", data: data);
              case 401:
                return DioResponse(code: errCode, message: "没有权限", data: data);
              case 403:
                return DioResponse(
                    code: errCode, message: "服务器拒绝执行", data: data);
              case 404:
                return DioResponse(
                    code: errCode, message: "无法连接服务器", data: data);
              case 405:
                return DioResponse(
                    code: errCode, message: "请求方法被禁止", data: data);
              case 500:
                return DioResponse(
                    code: errCode, message: "服务器内部错误", data: data);
              case 502:
                return DioResponse(code: errCode, message: "无效的请求", data: data);
              case 503:
                return DioResponse(code: errCode, message: "服务器挂了", data: data);
              case 505:
                return DioResponse(
                    code: errCode, message: "不支持HTTP协议请求", data: data);
              default:
                return DioResponse(
                    code: errCode,
                    message: error.response != null
                        ? error.response!.statusMessage!
                        : "其他状态字异常",
                    data: data);
            }
          } on Exception catch (_) {
            return DioResponse(code: -1, message: "unknown抛出了异常", data: data);
          }
        }
      default:
        {
          return DioResponse(
              code: -1, message: error.message.toString(), data: data);
        }
    }
  }

5.对错误信息进行统一的处理

//error进行统一处理
 onError(DioResponse eInfo) {
   debugPrint('错误----代码:${eInfo.code.toString()}, 错误内容:${eInfo.message}');
   String errText = '';
   switch (eInfo.code) {
     case 401: //401提示什么错误或者做些什么操作,比如token过期退出登录
 
       switch (eInfo.message) {
         case "Token has expired":
         case "Authentication failed":
           errText = "账号登录已过期,请重新登陆".tr;
           EasyLoading.showError(errText);
           Get.offNamed(AppRoutes.SIGN_IN);
           break;
         case "Invalid username or password":
           EasyLoading.showError("账号或密码不正确".tr);
           break;
         case "User account is not active":
         case "User account is locked due to security policy":
           break;
       }
 
       break;
     case 501:
       switch (eInfo.message) {
         case "The user does not exist, please register!":
           errText = "该账号不存在".tr;
           EasyLoading.showError(errText);
           break;
         case "User already exists!":
           errText = "用户已存在".tr;
           EasyLoading.showError(errText);
           break;
       }
 
       break;
     case 509:
       print("+++++++++++++++++++");
       errText = "验证码有误,请重新获取".tr;
       EasyLoading.showError(errText);
       break;
 
     case 511:
       errText = "验证码以过期,请重新输入".tr;
       EasyLoading.showError(errText);
       break;
     case 403:
       errText = "该账号没有权限登录,请联系管理员".tr;
       EasyLoading.showError(errText);
       break;
     case -1:
       EasyLoading.showError(eInfo.message);
       break;
 
     default:
       //用弹窗提示错误
       errText = "未知错误".tr;
       EasyLoading.showError(errText);
   }
 }

6.配置请求类型和取消请求功能

//error进行统一处理
  onError(DioResponse eInfo) {
    debugPrint('错误----代码:${eInfo.code.toString()}, 错误内容:${eInfo.message}');
    String errText = '';
    switch (eInfo.code) {
      case 401: //401提示什么错误或者做些什么操作,比如token过期退出登录
 
        switch (eInfo.message) {
          case "Token has expired":
          case "Authentication failed":
            errText = "账号登录已过期,请重新登陆".tr;
            EasyLoading.showError(errText);
            Get.offNamed(AppRoutes.SIGN_IN);
            break;
          case "Invalid username or password":
            EasyLoading.showError("账号或密码不正确".tr);
            break;
          case "User account is not active":
          case "User account is locked due to security policy":
            break;
        }
 
        break;
      case 501:
        switch (eInfo.message) {
          case "The user does not exist, please register!":
            errText = "该账号不存在".tr;
            EasyLoading.showError(errText);
            break;
          case "User already exists!":
            errText = "用户已存在".tr;
            EasyLoading.showError(errText);
            break;
        }
 
        break;
      case 509:
        print("+++++++++++++++++++");
        errText = "验证码有误,请重新获取".tr;
        EasyLoading.showError(errText);
        break;
 
      case 511:
        errText = "验证码以过期,请重新输入".tr;
        EasyLoading.showError(errText);
        break;
      case 403:
        errText = "该账号没有权限登录,请联系管理员".tr;
        EasyLoading.showError(errText);
        break;
      case -1:
        EasyLoading.showError(eInfo.message);
        break;
 
      default:
        //用弹窗提示错误
        errText = "未知错误".tr;
        EasyLoading.showError(errText);
    }
  }
 
//错误信息
  DioResponse createErrorEntity(DioError error) {
    // print('error.type${error.type}');
    var data = error.response?.data;
    print(
        "进入了错误信息:error.type:${error.type},错误的码:¥「${error.response!.statusCode},,data:¥${data}");
    switch (error.type) {
      case DioErrorType.cancel:
        return DioResponse(code: -1, message: "请求取消", data: data);
      case DioErrorType.connectionTimeout:
        return DioResponse(code: -1, message: "连接超时", data: data);
      case DioErrorType.sendTimeout:
        return DioResponse(code: -1, message: "请求超时", data: data);
      case DioErrorType.receiveTimeout:
        return DioResponse(code: -1, message: "响应超时", data: data);
      case DioErrorType.badResponse:
        try {
          print("data:$data");
          int errCode =
              error.response != null ? error.response!.statusCode! : -1;
 
          return DioResponse(
              code: errCode, message: data["message"], data: data);
        } catch (e) {
          return DioResponse(code: -1, message: "badResponse抛出了异常", data: e);
        }
 
      case DioErrorType.unknown:
        {
          try {
            int errCode =
                error.response != null ? error.response!.statusCode! : -1;
 
            switch (errCode) {
              case 400:
                return DioResponse(
                    code: errCode, message: "请求语法错误", data: data);
              case 401:
                return DioResponse(code: errCode, message: "没有权限", data: data);
              case 403:
                return DioResponse(
                    code: errCode, message: "服务器拒绝执行", data: data);
              case 404:
                return DioResponse(
                    code: errCode, message: "无法连接服务器", data: data);
              case 405:
                return DioResponse(
                    code: errCode, message: "请求方法被禁止", data: data);
              case 500:
                return DioResponse(
                    code: errCode, message: "服务器内部错误", data: data);
              case 502:
                return DioResponse(code: errCode, message: "无效的请求", data: data);
              case 503:
                return DioResponse(code: errCode, message: "服务器挂了", data: data);
              case 505:
                return DioResponse(
                    code: errCode, message: "不支持HTTP协议请求", data: data);
              default:
                return DioResponse(
                    code: errCode,
                    message: error.response != null
                        ? error.response!.statusMessage!
                        : "其他状态字异常",
                    data: data);
            }
          } on Exception catch (_) {
            return DioResponse(code: -1, message: "unknown抛出了异常", data: data);
          }
        }
      default:
        {
          return DioResponse(
              code: -1, message: error.message.toString(), data: data);
        }
    }
  }
 
  /// 取消请求
  /// 同一个cancel token 可以用于多个请求,当一个cancel token取消时,所有使用该cancel token的请求都会被取消。
  /// 所以参数可选
  void cancelRequests(CancelToken token) {
    token.cancel("cancelled");
  }
 
  /// 读取本地配置
  Map<String, dynamic>? getAuthorizationHeader() {
    var headers = <String, dynamic>{};
    var token = StorageUtil().read("token");
    print("token");
    if (token != null) {
      headers['X-Authorization'] = 'Bearer $token';
    }
    return headers;
  }
 
  /// restful get 操作
  /// refresh 是否下拉刷新 默认 false
  /// noCache 是否不缓存 默认 true
  /// list 是否列表 默认 false
  /// cacheKey 缓存key
  /// cacheDisk 是否磁盘缓存
  Future get(
    String path, {
    Map<String, dynamic>? queryParameters,
    Options? options,
    bool refresh = false,
    bool noCache = !CACHE_ENABLE,
    bool list = false,
    String cacheKey = '',
    bool cacheDisk = false,
    CancelToken? canceltoken,
    Map<String, dynamic>? data,
  }) async {
    Options requestOptions = options ?? Options();
    requestOptions.headers = requestOptions.headers ?? {};
    Map<String, dynamic>? authorization = getAuthorizationHeader();
    if (authorization != null) {
      requestOptions.headers!.addAll(authorization);
    }
 
    try {
      print("入参:$path--$data");
      var response = await dio.get(
        path,
        queryParameters: queryParameters,
        options: requestOptions,
        cancelToken: canceltoken ?? cancelToken,
        data: data,
      );
      print("+++++++++++++++:$response");
      return response.data;
    } catch (e) {
      print("出现了错误$e");
    }
  }
 
  /// restful post 操作
  Future post(
    String path, {
    dynamic data,
    Map<String, dynamic>? queryParameters,
    Options? options,
    CancelToken? canceltoken,
  }) async {
    Options requestOptions = options ?? Options();
    requestOptions.headers = requestOptions.headers ?? {};
    Map<String, dynamic>? authorization = getAuthorizationHeader();
 
    if (authorization != null) {
      requestOptions.headers!.addAll(authorization);
    }
    try {
      var response = await dio.post(
        path,
        data: data,
        queryParameters: queryParameters,
        options: requestOptions,
        cancelToken: canceltoken ?? cancelToken,
      );
      return response.data;
    } catch (e) {
      print("出现了错误:$e");
      return e;
    }
  }
 
  /// restful put 操作
  Future put(
    String path, {
    dynamic data,
    Map<String, dynamic>? queryParameters,
    Options? options,
  }) async {
    Options requestOptions = options ?? Options();
    requestOptions.headers = requestOptions.headers ?? {};
    Map<String, dynamic>? authorization = getAuthorizationHeader();
    if (authorization != null) {
      requestOptions.headers!.addAll(authorization);
    }
    var response = await dio.put(
      path,
      data: data,
      queryParameters: queryParameters,
      options: requestOptions,
      cancelToken: cancelToken,
    );
    return response.data;
  }
 
  /// restful patch 操作
  Future patch(
    String path, {
    dynamic data,
    Map<String, dynamic>? queryParameters,
    Options? options,
  }) async {
    Options requestOptions = options ?? Options();
    requestOptions.headers = requestOptions.headers ?? {};
    Map<String, dynamic>? authorization = getAuthorizationHeader();
    if (authorization != null) {
      requestOptions.headers!.addAll(authorization);
    }
    var response = await dio.patch(
      path,
      data: data,
      queryParameters: queryParameters,
      options: requestOptions,
      cancelToken: cancelToken,
    );
    return response.data;
  }
 
  /// restful delete 操作
  Future delete(
    String path, {
    dynamic data,
    Map<String, dynamic>? queryParameters,
    Options? options,
  }) async {
    Options requestOptions = options ?? Options();
    requestOptions.headers = requestOptions.headers ?? {};
    Map<String, dynamic>? authorization = getAuthorizationHeader();
    if (authorization != null) {
      requestOptions.headers!.addAll(authorization);
    }
    var response = await dio.delete(
      path,
      data: data,
      queryParameters: queryParameters,
      options: requestOptions,
      cancelToken: cancelToken,
    );
    return response.data;
  }
 
  /// restful post form 表单提交操作
  Future postForm(
    String path, {
    dynamic data,
    Map<String, dynamic>? queryParameters,
    Options? options,
  }) async {
    Options requestOptions = options ?? Options();
    requestOptions.headers = requestOptions.headers ?? {};
    Map<String, dynamic>? authorization = getAuthorizationHeader();
    if (authorization != null) {
      requestOptions.headers!.addAll(authorization);
    }
    var response = await dio.post(
      path,
      data: FormData.fromMap(data),
      queryParameters: queryParameters,
      options: requestOptions,
      cancelToken: cancelToken,
    );
    return response.data;
  }
 
  /// restful post Stream 流数据
  Future postStream(
    String path, {
    dynamic data,
    int dataLength = 0,
    Map<String, dynamic>? queryParameters,
    Options? options,
  }) async {
    Options requestOptions = options ?? Options();
    requestOptions.headers = requestOptions.headers ?? {};
    Map<String, dynamic>? authorization = getAuthorizationHeader();
    if (authorization != null) {
      requestOptions.headers!.addAll(authorization);
    }
    requestOptions.headers!.addAll({
      Headers.contentLengthHeader: dataLength.toString(),
    });
    var response = await dio.post(
      path,
      data: Stream.fromIterable(data.map((e) => [e])),
      queryParameters: queryParameters,
      options: requestOptions,
      cancelToken: cancelToken,
    );
    return response.data;
  }
}

7.全部代码

import 'dart:math';
 
import 'package:cookie_jar/cookie_jar.dart';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart' as tr;
import 'package:get/get_core/src/get_main.dart';
import 'package:my_app/common/routes/routes.dart';
import 'package:my_app/common/utils/utils.dart';
import 'package:my_app/common/value/serve.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:dio_cookie_manager/dio_cookie_manager.dart';
// import 'package:get/get.dart';
// import 'package:dio/src/form_data.dart';
import './../value/cache.dart';
 
class HttpUtil {
  static final HttpUtil _instance = HttpUtil.internal();
  factory HttpUtil() => _instance;
 
  late Dio dio;
  //可以通过 CancelToken 来取消发起的请求
  CancelToken cancelToken = CancelToken();
 
  HttpUtil.internal() {
    // BaseOptions、Options、RequestOptions 都可以配置参数,优先级别依次递增,且可以根据优先级别覆盖参数
    BaseOptions options = BaseOptions(
      //请求基地址
      baseUrl: SERVER_API_URL,
 
      // baseUrl: storage.read(key: STORAGE_KEY_APIURL) ?? SERVICE_API_BASEURL,
      //连接服务器超时时间
      connectTimeout: const Duration(seconds: 20),
      // 响应流上前后两次接受到数据的间隔
      receiveTimeout: const Duration(seconds: 20),
      // Http请求头.
      headers: {},
 
      /// 请求的Content-Type,默认值是"application/json; charset=utf-8".
      /// 如果您想以"application/x-www-form-urlencoded"格式编码请求数据,
      /// 可以设置此选项为 `Headers.formUrlEncodedContentType`,  这样[Dio]
      /// 就会自动编码请求体.
      contentType: 'application/json; charset=utf-8',
 
      /// [responseType] 表示期望以那种格式(方式)接受响应数据。
      /// 目前 [ResponseType] 接受三种类型 `JSON`, `STREAM`, `PLAIN`.
      ///
      /// 默认值是 `JSON`, 当响应头中content-type为"application/json"时,dio 会自动将响应内容转化为json对象。
      /// 如果想以二进制方式接受响应数据,如下载一个二进制文件,那么可以使用 `STREAM`.
      ///
      /// 如果想以文本(字符串)格式接收响应数据,请使用 `PLAIN`.
      responseType: ResponseType.json,
    );
    dio = Dio(options);
    // CookieJar   Dart 中用于 http 请求的 cookie 管理器,您可以通过它轻松处理复杂的 cookie 策略并持久化 cookie。
    // CookieJar cookieJar = CookieJar();
    // dio.interceptors.add(CookieManager(cookieJar));
 
    // 添加拦截器
    dio.interceptors.add(
      InterceptorsWrapper(
        onRequest: (RequestOptions options, RequestInterceptorHandler handler) {
          /// 如果你想完成请求并返回一些自定义数据,你可以使用 `handler.resolve(response)`。
          ///这样请求将会被终止,上层then会被调用,then中返回的数据将是你的自定义response.
 
          /// 如果你想终止请求并触发一个错误,你可以使用 `handler.reject(error)`。
          /// 这样请求将被中止并触发异常,上层catchError会被调用。
          ///
          return handler.next(options);
        },
        onResponse: (response, handler) {
          // 如果你想终止请求并触发一个错误,你可以使用 `handler.reject(error)`。
          //这样请求将被中止并触发异常,上层catchError会被调用。
          // 请求成功是对数据做基本处理
 
          if (response.statusCode == 200) {
            response.data =
                DioResponse(code: 200, message: "请求成功啦", data: response.data);
          } else {
            response.data = DioResponse(
                code: response.statusCode,
                message: "请求失败啦",
                data: response.data);
          }
          // 对某些单独的url返回数据做特殊处理
          // if (response.requestOptions.baseUrl.contains("???????")) {
          //   //....
          // }
 
          return handler.next(response);
        },
        onError: (e, handler) {
          //停止加载
          // Loading.dismiss();
          print("-=-=-=-onError$e,-----$handler");
 
          EasyLoading.instance.userInteractions = true;
          EasyLoading.dismiss();
          DioResponse? eInfo;
          if ("$e".contains("The request connection took longer")) {
            eInfo = DioResponse(code: -1, message: "连接超时", data: "");
          } else {
            eInfo = createErrorEntity(e);
          }
 
          // print("111111111:$eInfo");
 
          onError(eInfo);
 
          Response response =
              Response(data: eInfo, requestOptions: RequestOptions());
 
          // e.data =eInfo;
 
          return handler.resolve(response); //continue
 
          // 如果你想完成请求并返回一些自定义数据,可以resolve 一个`Response`,如`handler.resolve(response)`。
          // 这样请求将会被终止,上层then会被调用,then中返回的数据将是你的自定义response.
        },
      ),
    );
  }
 
  //error进行统一处理
  onError(DioResponse eInfo) {
    debugPrint('错误----代码:${eInfo.code.toString()}, 错误内容:${eInfo.message}');
    String errText = '';
    switch (eInfo.code) {
      case 401: //401提示什么错误或者做些什么操作,比如token过期退出登录
 
        switch (eInfo.message) {
          case "Token has expired":
          case "Authentication failed":
            errText = "账号登录已过期,请重新登陆".tr;
            EasyLoading.showError(errText);
            Get.offNamed(AppRoutes.SIGN_IN);
            break;
          case "Invalid username or password":
            EasyLoading.showError("账号或密码不正确".tr);
            break;
          case "User account is not active":
          case "User account is locked due to security policy":
            break;
        }
 
        break;
      case 501:
        switch (eInfo.message) {
          case "The user does not exist, please register!":
            errText = "该账号不存在".tr;
            EasyLoading.showError(errText);
            break;
          case "User already exists!":
            errText = "用户已存在".tr;
            EasyLoading.showError(errText);
            break;
        }
 
        break;
      case 509:
        print("+++++++++++++++++++");
        errText = "验证码有误,请重新获取".tr;
        EasyLoading.showError(errText);
        break;
 
      case 511:
        errText = "验证码以过期,请重新输入".tr;
        EasyLoading.showError(errText);
        break;
      case 403:
        errText = "该账号没有权限登录,请联系管理员".tr;
        EasyLoading.showError(errText);
        break;
      case -1:
        EasyLoading.showError(eInfo.message);
        break;
 
      default:
        //用弹窗提示错误
        errText = "未知错误".tr;
        EasyLoading.showError(errText);
    }
  }
 
//错误信息
  DioResponse createErrorEntity(DioError error) {
    // print('error.type${error.type}');
    var data = error.response?.data;
    print(
        "进入了错误信息:error.type:${error.type},错误的码:¥「${error.response!.statusCode},,data:¥${data}");
    switch (error.type) {
      case DioErrorType.cancel:
        return DioResponse(code: -1, message: "请求取消", data: data);
      case DioErrorType.connectionTimeout:
        return DioResponse(code: -1, message: "连接超时", data: data);
      case DioErrorType.sendTimeout:
        return DioResponse(code: -1, message: "请求超时", data: data);
      case DioErrorType.receiveTimeout:
        return DioResponse(code: -1, message: "响应超时", data: data);
      case DioErrorType.badResponse:
        try {
          print("data:$data");
          int errCode =
              error.response != null ? error.response!.statusCode! : -1;
 
          return DioResponse(
              code: errCode, message: data["message"], data: data);
        } catch (e) {
          return DioResponse(code: -1, message: "badResponse抛出了异常", data: e);
        }
 
      case DioErrorType.unknown:
        {
          try {
            int errCode =
                error.response != null ? error.response!.statusCode! : -1;
 
            switch (errCode) {
              case 400:
                return DioResponse(
                    code: errCode, message: "请求语法错误", data: data);
              case 401:
                return DioResponse(code: errCode, message: "没有权限", data: data);
              case 403:
                return DioResponse(
                    code: errCode, message: "服务器拒绝执行", data: data);
              case 404:
                return DioResponse(
                    code: errCode, message: "无法连接服务器", data: data);
              case 405:
                return DioResponse(
                    code: errCode, message: "请求方法被禁止", data: data);
              case 500:
                return DioResponse(
                    code: errCode, message: "服务器内部错误", data: data);
              case 502:
                return DioResponse(code: errCode, message: "无效的请求", data: data);
              case 503:
                return DioResponse(code: errCode, message: "服务器挂了", data: data);
              case 505:
                return DioResponse(
                    code: errCode, message: "不支持HTTP协议请求", data: data);
              default:
                return DioResponse(
                    code: errCode,
                    message: error.response != null
                        ? error.response!.statusMessage!
                        : "其他状态字异常",
                    data: data);
            }
          } on Exception catch (_) {
            return DioResponse(code: -1, message: "unknown抛出了异常", data: data);
          }
        }
      default:
        {
          return DioResponse(
              code: -1, message: error.message.toString(), data: data);
        }
    }
  }
 
  /// 取消请求
  /// 同一个cancel token 可以用于多个请求,当一个cancel token取消时,所有使用该cancel token的请求都会被取消。
  /// 所以参数可选
  void cancelRequests(CancelToken token) {
    token.cancel("cancelled");
  }
 
  /// 读取本地配置
  Map<String, dynamic>? getAuthorizationHeader() {
    var headers = <String, dynamic>{};
    var token = StorageUtil().read("token");
    print("token");
    if (token != null) {
      headers['X-Authorization'] = 'Bearer $token';
    }
    return headers;
  }
 
  /// restful get 操作
  /// refresh 是否下拉刷新 默认 false
  /// noCache 是否不缓存 默认 true
  /// list 是否列表 默认 false
  /// cacheKey 缓存key
  /// cacheDisk 是否磁盘缓存
  Future get(
    String path, {
    Map<String, dynamic>? queryParameters,
    Options? options,
    bool refresh = false,
    bool noCache = !CACHE_ENABLE,
    bool list = false,
    String cacheKey = '',
    bool cacheDisk = false,
    CancelToken? canceltoken,
    Map<String, dynamic>? data,
  }) async {
    Options requestOptions = options ?? Options();
    requestOptions.headers = requestOptions.headers ?? {};
    Map<String, dynamic>? authorization = getAuthorizationHeader();
    if (authorization != null) {
      requestOptions.headers!.addAll(authorization);
    }
 
    try {
      print("入参:$path--$data");
      var response = await dio.get(
        path,
        queryParameters: queryParameters,
        options: requestOptions,
        cancelToken: canceltoken ?? cancelToken,
        data: data,
      );
      print("+++++++++++++++:$response");
      return response.data;
    } catch (e) {
      print("出现了错误$e");
    }
  }
 
  /// restful post 操作
  Future post(
    String path, {
    dynamic data,
    Map<String, dynamic>? queryParameters,
    Options? options,
    CancelToken? canceltoken,
  }) async {
    Options requestOptions = options ?? Options();
    requestOptions.headers = requestOptions.headers ?? {};
    Map<String, dynamic>? authorization = getAuthorizationHeader();
 
    if (authorization != null) {
      requestOptions.headers!.addAll(authorization);
    }
    try {
      var response = await dio.post(
        path,
        data: data,
        queryParameters: queryParameters,
        options: requestOptions,
        cancelToken: canceltoken ?? cancelToken,
      );
      return response.data;
    } catch (e) {
      print("出现了错误:$e");
      return e;
    }
  }
 
  /// restful put 操作
  Future put(
    String path, {
    dynamic data,
    Map<String, dynamic>? queryParameters,
    Options? options,
  }) async {
    Options requestOptions = options ?? Options();
    requestOptions.headers = requestOptions.headers ?? {};
    Map<String, dynamic>? authorization = getAuthorizationHeader();
    if (authorization != null) {
      requestOptions.headers!.addAll(authorization);
    }
    var response = await dio.put(
      path,
      data: data,
      queryParameters: queryParameters,
      options: requestOptions,
      cancelToken: cancelToken,
    );
    return response.data;
  }
 
  /// restful patch 操作
  Future patch(
    String path, {
    dynamic data,
    Map<String, dynamic>? queryParameters,
    Options? options,
  }) async {
    Options requestOptions = options ?? Options();
    requestOptions.headers = requestOptions.headers ?? {};
    Map<String, dynamic>? authorization = getAuthorizationHeader();
    if (authorization != null) {
      requestOptions.headers!.addAll(authorization);
    }
    var response = await dio.patch(
      path,
      data: data,
      queryParameters: queryParameters,
      options: requestOptions,
      cancelToken: cancelToken,
    );
    return response.data;
  }
 
  /// restful delete 操作
  Future delete(
    String path, {
    dynamic data,
    Map<String, dynamic>? queryParameters,
    Options? options,
  }) async {
    Options requestOptions = options ?? Options();
    requestOptions.headers = requestOptions.headers ?? {};
    Map<String, dynamic>? authorization = getAuthorizationHeader();
    if (authorization != null) {
      requestOptions.headers!.addAll(authorization);
    }
    var response = await dio.delete(
      path,
      data: data,
      queryParameters: queryParameters,
      options: requestOptions,
      cancelToken: cancelToken,
    );
    return response.data;
  }
 
  /// restful post form 表单提交操作
  Future postForm(
    String path, {
    dynamic data,
    Map<String, dynamic>? queryParameters,
    Options? options,
  }) async {
    Options requestOptions = options ?? Options();
    requestOptions.headers = requestOptions.headers ?? {};
    Map<String, dynamic>? authorization = getAuthorizationHeader();
    if (authorization != null) {
      requestOptions.headers!.addAll(authorization);
    }
    var response = await dio.post(
      path,
      data: FormData.fromMap(data),
      queryParameters: queryParameters,
      options: requestOptions,
      cancelToken: cancelToken,
    );
    return response.data;
  }
 
  /// restful post Stream 流数据
  Future postStream(
    String path, {
    dynamic data,
    int dataLength = 0,
    Map<String, dynamic>? queryParameters,
    Options? options,
  }) async {
    Options requestOptions = options ?? Options();
    requestOptions.headers = requestOptions.headers ?? {};
    Map<String, dynamic>? authorization = getAuthorizationHeader();
    if (authorization != null) {
      requestOptions.headers!.addAll(authorization);
    }
    requestOptions.headers!.addAll({
      Headers.contentLengthHeader: dataLength.toString(),
    });
    var response = await dio.post(
      path,
      data: Stream.fromIterable(data.map((e) => [e])),
      queryParameters: queryParameters,
      options: requestOptions,
      cancelToken: cancelToken,
    );
    return response.data;
  }
}
 
class DioResponse<T> {
  /// 消息(例如成功消息文字/错误消息文字)
  final String message;
 
  /// 自定义code(可根据内部定义方式)
  final int? code;
 
  /// 接口返回的数据
  final T data;
 
  /// 需要添加更多
  /// .........
 
  DioResponse({
    required this.message,
    required this.data,
    required this.code,
  });
  factory DioResponse.fromJson(Map<String, dynamic> json) => DioResponse(
        code: json["code"],
        message: json["message"],
        data: json["data"],
      );
  Map<String, dynamic> toJson() => {
        "message": message,
        "data": data,
        "code": code,
      };
}
相关推荐
江上清风山间明月1 小时前
Flutter开发的应用页面非常多时如何高效管理路由
android·flutter·路由·页面管理·routes·ongenerateroute
Zsnoin能12 小时前
flutter国际化、主题配置、视频播放器UI、扫码功能、水波纹问题
flutter
早起的年轻人12 小时前
Flutter CupertinoNavigationBar iOS 风格导航栏的组件
flutter·ios
HappyAcmen12 小时前
关于Flutter前端面试题及其答案解析
前端·flutter
coooliang1 天前
Flutter 中的单例模式
javascript·flutter·单例模式
coooliang1 天前
Flutter项目中设置安卓启动页
android·flutter
JIngles1231 天前
flutter将utf-8编码的字节序列转换为中英文字符串
java·javascript·flutter
B.-1 天前
在 Flutter 中实现文件读写
开发语言·学习·flutter·android studio·xcode
freflying11191 天前
使用jenkins构建Android+Flutter项目依赖自动升级带来兼容性问题及Jenkins构建速度慢问题解决
android·flutter·jenkins
机器瓦力1 天前
Flutter应用开发:对象存储管理图片
flutter