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.mzph.cn/diannao/61158.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

tcp 超时计时器

在 TCP&#xff08;传输控制协议&#xff09;中有以下四种重要的计时器&#xff1a; 重传计时器&#xff08;Retransmission Timer&#xff09; 作用&#xff1a;用于处理数据包丢失的情况。当发送方发送一个数据段后&#xff0c;就会启动重传计时器。如果在计时器超时之前没有…

前端(4)——demo分享

这两天需要用HTML、CSS和js简单组合一个html网页用于展示一些数据内容&#xff0c;这是我简单组合别人的一些文件形成的简单demo&#xff0c;大家也可以拿过去使用。 登录界面&#xff1a; 场景选择界面&#xff0c;有五个场景&#xff0c;每个场景中都需要展示一些特定的数据…

Java-空链处理

什么是 null 在 Java 中&#xff0c;null 是一个非常常见的关键字&#xff0c;用于表示“没有值”或“空”。然而&#xff0c;对于初学者来说&#xff0c;null 的本质可能会感到有些困惑。在本文中&#xff0c;我们将详细探讨 null 在 Java 中的含义和使用。 在 Java 中&…

PyTorch使用教程-深度学习框架

PyTorch使用教程-深度学习框架 1. PyTorch简介 1.1-什么是PyTorch ​ PyTorch是一个广泛使用的开源机器学习框架&#xff0c;特别适合深度学习的应用。它以其动态计算图而闻名&#xff0c;允许在运行时修改模型&#xff0c;使得实验和调试更加灵活。PyTorch提供了强大的GPU加…

供应链管理、一件代发系统功能及源码分享 PHP+Mysql

随着电商行业的不断发展&#xff0c;传统的库存管理模式已经逐渐无法满足市场需求。越来越多的企业选择“一件代发”模式&#xff0c;即商家不需要自己储备商品库存&#xff0c;而是将订单直接转给供应商&#xff0c;由供应商直接进行发货。这种方式极大地降低了企业的运营成本…

Pr:音频过渡

Adobe Premiere Pro 自带一组共三个音频过渡 Audio Transitions效果。 对音频剪辑之间应用交叉淡化 Crossfade过渡&#xff0c;操作方式类似于应用视频过渡效果。 对于交叉淡化&#xff0c;要保证前剪辑的出点之后及后剪辑的入点之前有足够的预留内容&#xff08;也称“手柄”&…

前端页面开发步骤详解

目录 前言1. 页面搭建1.1 HTML 标签结构1.2 CSS 样式设计 2. 数据绑定与事件处理2.1 数据绑定2.2 表单校验 3. 调用后台接口3.1 接口文档与工具封装3.2 参数传递与接口调用 结语 前言 在前端开发过程中&#xff0c;从页面搭建到与后台接口对接是一个必不可少的完整流程。无论是…

A037-基于Spring Boot的二手物品交易的设计与实现

&#x1f64a;作者简介&#xff1a;在校研究生&#xff0c;拥有计算机专业的研究生开发团队&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的网站项目。 代码可以查看文章末尾⬇️联系方式获取&#xff0c;记得注明来意哦~&#x1f339; 赠送计算机毕业设计600…

两行命令搭建深度学习环境(Docker/torch2.5.1+cu118/命令行美化+插件),含完整的 Docker 安装步骤

深度学习环境的配置过于繁琐&#xff0c;所以我制作了两个基础的镜像&#xff0c;希望可以帮助大家节省时间&#xff0c;你可以选择其中一种进行安装&#xff0c;版本说明&#xff1a; base 版本基于 pytorch/pytorch:2.5.1-cuda11.8-cudnn9-devel&#xff0c;默认 python 版本…

EXCEL延迟退休公式

如图&#xff1a; A B为手工输入 C2EOMONTH(A2,B2*12) D2EOMONTH(C2,IF(C2>DATEVALUE("2025-1-1"),INT((DATEDIF(DATEVALUE("2025-1-1"),C2,"m")4)/4),0)) E2EOMONTH(A2,B2*12IF(EOMONTH(A2,B2*12)>DATEVALUE("2025-1-1"),INT(…

区块链技术在数据安全中的应用

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 区块链技术在数据安全中的应用 区块链技术在数据安全中的应用 区块链技术在数据安全中的应用 引言 区块链技术基础 1.1 区块链的…

GIT 入门详解指南

前言&#xff1a; 注&#xff1a;本博客仅用于记录本人学习过程中对git的理解&#xff0c;仅供学习参考&#xff0c;如有异议请自行查资料求证 安装 使用git之前必须完成git的安装&#xff0c;Git 目前支持 Linux/Unix、Solaris、Mac和 Windows 平台上运行 git 安装教程 基本…

讯飞、阿里云、腾讯云:Android 语音合成服务对比选择

在 移动端 接入语音合成方面&#xff0c;讯飞和腾讯云等都是优秀的选择&#xff0c;但各有其特点和优势。咱们的需求是需要支持普通话/英语/法语三种语言&#xff0c;以下是对各个平台的详细比较&#xff1a; 一、讯飞语音合成介绍 与语音听写相反&#xff0c;语音合成是将一段…

HarmonyOS本地存储-Preferences(用户首选项)的使用

一&#xff0c;用户首选项简述 ohos.data.preferences (用户首选项) 用户首选项为应用提供Key-Value键值型的数据处理能力&#xff0c;支持应用持久化轻量级数据&#xff0c;并对其修改和查询。 数据存储形式为键值对&#xff0c;键的类型为字符串型&#xff0c;值的存储数据…

【机器学习】回归模型(线性回归+逻辑回归)原理详解

线性回归 Linear Regression 1 概述 线性回归类似高中的线性规划题目。线性回归要做的是就是找到一个数学公式能相对较完美地把所有自变量组合&#xff08;加减乘除&#xff09;起来&#xff0c;得到的结果和目标接近。 线性回归分为一元线性回归和多元线性回归。 2 一元线…

OceanBase 分区表详解

1、分区表的定义 在OceanBase数据库中&#xff0c;普通的表数据可以根据预设的规则被分割并存储到不同的数据区块中&#xff0c;同一区块的数据是在一个物理存储上。这样被分区块的表被称为分区表&#xff0c;而其中的每一个独立的数据区块则被称为一个分区。 如下图所示&…

【Android原生问题分析】夸克、抖音划动无响应问题【Android14】

1 问题描述 偶现问题&#xff0c;用户打开夸克、抖音后&#xff0c;在界面上划动无响应&#xff0c;但是没有ANR。回到Launcher后再次打开夸克/抖音&#xff0c;发现App的界面发生了变化&#xff0c;但是仍然是划不动的。 2 log初分析 复现问题附近的log为&#xff1a; 用户…

使用 K-means 算法进行豆瓣读书数据的文本聚类分析

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

Django5 2024全栈开发指南(二):Django项目配置详解

目录 一、基本配置信息二、资源文件配置2.1 资源路由——STATIC_URL2.2 资源集合——STATICFILES_DIRS2.3 资源部署——STATIC_ROOT2.2.4 媒体资源——MEDIA 三、模板配置四、数据库配置4.1 mysqlclient连接MySQL4.2 pymysql连接MySQL4.3 多个数据库的连接方式4.4 使用配置文件…

数据结构-二叉搜索树(Java语言)

目录 1.概念 2.查找search 3.插入insert ​编辑4.删除remove&#xff08;难点&#xff09; 5.性能分析 1.概念 二叉搜索树又称二叉排序树&#xff0c;它或者是一棵空树&#xff0c;或者是具有以下性质的二叉树 : 1.若它的左子树不为空&#xff0c;则左子树上所有节点的值都…