当前位置: 首页 > article >正文

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,
      };
}


http://www.kler.cn/a/399630.html

相关文章:

  • Java爬虫(Jsoup)详解
  • Spring Boot教程之Spring Boot简介
  • 《Java核心技术 卷I》用户界面中首选项API
  • C++网络编程之SSL/TLS加密通信
  • MongoDB在现代Web开发中的应用
  • 前端埋点、监控
  • 网络安全:数字时代的护城河
  • 机器学习笔记2 - 机器学习的一般流程
  • Unity-Editor扩展Odin + 自定义EditorWindow记录
  • Python正则表达式中re.M 是什么意思
  • Big Data for AI实践:面向AI大模型开发和应用的大规模数据处理套件
  • 【WPF】Prism学习(四)
  • 深入浅出 Go 语言:现代编程的高效选择
  • 【PGCCC】Postgresql 存储设计
  • Flink运行时架构以及核心概念
  • 基于SpringBoot+Vue的船舶维保管理系统(带1w+文档)
  • UE5的线程同步机制
  • 鸿蒙HarmonyOS 地图定位到当前位置 site查询等操作
  • Rewar Model的输出(不包含训练)
  • <有毒?!> 诺顿检测:这篇 CSDN 文章有病毒
  • Gin 框架中的路由
  • PostgreSQL高可用Patroni安装(超详细)
  • datalist 是什么?以及作用是什么?
  • Android 判断当前是否亮灭屏状态或黑屏锁屏状态
  • 小白快速上手 labelme:新手图像标注详解教程
  • 集群聊天服务器(3)muduo网络库