flutter dio 请求封装(空安全)
一、添加依赖
dio: ^5.3.2
二、请求封装
class HttpHelper {static Dio? mDio;static BaseOptions? options;static HttpHelper? httpHelper;CancelToken cancelToken = CancelToken();static const String GET = 'get';static const String POST = 'post';static const String PUT = 'put';static const String PATCH = 'patch';static const String DELETE = 'delete';static HttpHelper? get instance => getInstance();static Dio? get dio => getDio();static HttpHelper? getInstance() {httpHelper ??= HttpHelper();return httpHelper;}static Dio? getDio() {final token = GetStorage().read('token');final Map<String, dynamic> headerMap = {};if (token != null) {headerMap.putIfAbsent("Authorization", () => "Bearer $token");}options = BaseOptions(//请求基地址,可以包含子路径baseUrl: Api.BASE_URL,//连接服务器超时时间,单位是毫秒.connectTimeout: const Duration(seconds: 10),//2.x中为接收数据的最长时限receiveTimeout: const Duration(seconds: 5),//Http请求头.headers: headerMap,// 请求的Content-Type,默认值是"application/json; charset=utf-8".// /// 如果您想以"application/x-www-form-urlencoded"格式编码请求数据,// /// 可以设置此选项为 `Headers.formUrlEncodedContentType`, 这样[Dio]// /// 就会自动编码请求体.contentType: Headers.jsonContentType,/// [responseType] 表示期望以那种格式(方式)接受响应数据。/// 目前 [ResponseType] 接受三种类型 `JSON`, `STREAM`, `PLAIN`.////// 默认值是 `JSON`, 当响应头中content-type为"application/json"时,dio 会自动将响应内容转化为json对象。/// 如果想以二进制方式接受响应数据,如下载一个二进制文件,那么可以使用 `STREAM`.////// 如果想以文本(字符串)格式接收响应数据,请使用 `PLAIN`.responseType: ResponseType.json,);mDio = Dio(options);mDio?.interceptors.add(interceptorsWrapper());mDio?.httpClientAdapter = IOHttpClientAdapter(createHttpClient: () {final client = HttpClient();// Config the client.client.findProxy = (uri) {// Forward all request to proxy "localhost:8888".// Be aware, the proxy should went through you running device,// not the host platform.return 'PROXY 192.168.0.191:8089';};// You can also create a new HttpClient for Dio instead of returning,// but a client must being returned here.return client;},);return mDio;}static InterceptorsWrapper interceptorsWrapper() {return InterceptorsWrapper(onRequest: (options, handler) {// Do something before request is sentreturn handler.next(options); //continue// 如果你想完成请求并返回一些自定义数据,你可以resolve一个Response对象 `handler.resolve(response)`。// 这样请求将会被终止,上层then会被调用,then中返回的数据将是你的自定义response.//// 如果你想终止请求并触发一个错误,你可以返回一个`DioError`对象,如`handler.reject(error)`,// 这样请求将被中止并触发异常,上层catchError会被调用。}, onResponse: (response, handler) {// Do something with response datareturn handler.next(response); // continue// 如果你想终止请求并触发一个错误,你可以 reject 一个`DioError`对象,如`handler.reject(error)`,// 这样请求将被中止并触发异常,上层catchError会被调用。}, onError: (DioError e, handler) {// Do something with response errorif (e.response != null) {if (e.response?.statusCode == 401) {ToastMsg.show("当前登录已过期,请重新登录!");Future.delayed(const Duration(milliseconds: 1000), () {Get.offAllNamed(AppRoutes.LOGIN);});} else if (e.response?.statusCode == 403) {ToastMsg.show("暂无权限访问,请联系管理员!");} else {ToastMsg.show("系统内部异常!");}}return handler.next(e); //continue// 如果你想完成请求并返回一些自定义数据,可以resolve 一个`Response`,如`handler.resolve(response)`。// 这样请求将会被终止,上层then会被调用,then中返回的数据将是你的自定义response.});}///Get请求Future<BaseRes<T>> getHttp<T>(String url, parameters,{loading = true}) async {return await getResponse<T>(url, method: GET, parameters: parameters,loading:loading);}Future<BaseRes<T>> postHttp<T>(String url, parameters,{loading = true}) async {///定义请求参数parameters = parameters ?? <String, dynamic>{};return await getResponse<T>(url, method: POST, parameters: parameters,loading:loading);}Future<BaseRes<T>> putHttp<T>(String url, parameters,{loading = true}) async {///定义请求参数parameters = parameters ?? <String, dynamic>{};return await getResponse<T>(url, method: PUT, parameters: parameters,loading:loading);}Future<BaseRes<T>> deleteHttp<T>(String url, parameters,{loading = true}) async {///定义请求参数parameters = parameters ?? <String, dynamic>{};return await getResponse<T>(url, method: DELETE, parameters: parameters,loading:loading);}/** 下载文件*/downloadFile(urlPath, savePath, onReceiveProgress) async {Response? response;try {response = await dio?.download(urlPath, savePath,onReceiveProgress: onReceiveProgress);} on DioError catch (e) {formatError(e);}return response?.data;}Future<BaseRes<T>> getResponse<T>(String url, {required String method,parameters,loading,}) async {//这里指定response自动转成map,不指定的话有可能是String类型Response<Map<String, dynamic>>? response;if(loading) {ToastMsg.showLoading();}switch (method) {case GET:response = await dio?.get(url,queryParameters: parameters ?? <String, dynamic>{});break;case PUT:response = await dio?.put(url,queryParameters: parameters ?? <String, dynamic>{});break;case DELETE:response = await dio?.delete(url,queryParameters: parameters ?? <String, dynamic>{});break;default:response =await dio?.post(url, data: parameters ?? <String, dynamic>{});break;}if(loading) {ToastMsg.cancelLoading();}//200代表网络请求成功if (response?.statusCode == 200) {/// 将后台的data字段转成自己想要的数据/数据集,code根据后端实际返回进行判断访问结果BaseRes<T> bean = BaseRes.fromJson(response?.data);return bean;} else if (response?.statusCode == 401) {ToastMsg.show("当前登录已过期,请重新登录!");Future.delayed(const Duration(milliseconds: 1000), () {Get.offAllNamed(AppRoutes.LOGIN);});} else if (response?.statusCode == 403) {ToastMsg.show("暂无权限访问,请联系管理员!");} else {ToastMsg.show("系统内部异常!");}throw Exception('${response?.statusCode}+${response?.statusMessage}');}void formatError(DioError e) {print(e.message);}/** 取消请求* 同一个cancel token 可以用于多个请求,当一个cancel token取消时,所有使用该cancel token的请求都会被取消。*/void cancelRequests(CancelToken token) {token.cancel("cancelled");}
}
三、封装统一返回类
()
class BaseRes<T>{BaseRes(this.msg, this.code, this.data);late String msg;late int code;late T data;BaseRes.fromJson(Map<String, dynamic>? json) {if (json?['data'] != null && json?['data'] != 'null') {data = JsonConvert.fromJsonAsT<T>(json?['data']) as T;}msg = json?['msg'];code = json?['code'];}Map<String, dynamic> toJson() {final Map<String, dynamic> data = <String, dynamic>{};if (this.data != null) {data['data'] = this.data;}data['code'] = this.code;data['msg'] = this.msg;return data;}
}
四、使用
// Entity类使用的是JsonToDartBeanAction生成BaseRes<UserInfoEntity>? res = await HttpHelper.instance?.getHttp(Api.GET_USER_INGO,null,loading: false);if(res?.code == 200 && res?.data != null) {state.userInfo = res!.data.obs;}
相关文章:
flutter dio 请求封装(空安全)
一、添加依赖 dio: ^5.3.2二、请求封装 class HttpHelper {static Dio? mDio;static BaseOptions? options;static HttpHelper? httpHelper;CancelToken cancelToken CancelToken();static const String GET get;static const String POST post;static const String PU…...
chatgpt GPT-4V是如何实现语音对话的
直接上代码 https://chat.openai.com/voice/get_token 1. 请求内容 Request:GET /voice/get_token HTTP/1.1 Host: ios.chat.openai.com Content-Type: application/json Cookie: _puiduser***Fc9T:16962276****Nph%2Fb**SU%3D; _uasid"Z0FBQUF***nPT0"; __cf_bmBUg…...
C++项目-求水仙花数
求水仙花数 #include <iostream> using namespace std;int main() {int n 100;do {int a 0;int b 0;int c 0;a n % 10; //个位b n / 10 % 10; //十位c n / 100 % 10; //百位if (a * a * a b * b * b c * c * c n) {cout << n << endl;}…...
从零开始基于LLM构建智能问答系统的方案
本文首发于博客 LLM应用开发实践 一个完整的基于 LLM 的端到端问答系统,应该包括用户输入检验、问题分流、模型响应、回答质量评估、Prompt 迭代、回归测试,随着规模增大,围绕 Prompt 的版本管理、自动化测试和安全防护也是重要的话题&#x…...
Android---Synchronized 和 ReentrantLock
Synchronized 基本使用 1. 修饰实例方法 public class SynchronizedMethods{private int sum 0;public synchronized void calculate(){sum sum 1;} } 这种情况下的锁对象是当前实例对象,因此只有同一个实例对象调用此方法才会产生互斥效果;不同的…...
【解题报告】牛客挑战赛70 maimai
题目链接 这个挑战赛的 F F F是我出的,最后 zhoukangyang 爆标了。。。orzorz 记所有有颜色的边的属性集合 S S S 。 首先在外层容斥,枚举 S ∈ [ 0 , 2 w ) S\in [0,2^w) S∈[0,2w),计算被覆盖的的边中不包含 S S S 中属性,…...
算启新程 智享未来 | 紫光展锐携手中国移动共创数智未来
10月11日-13日,2023年中国移动全球合作伙伴大会在广州举行,此次大会以“算启新程 智享未来”为主题,与合作伙伴一起共商融合创新,共创数智未来。作为中国移动每年规模最大、最具影响力的盛会,吸引了数百家世界500强企业…...
thinkphp5.1 获取缓存cache(‘cache_name‘)特别慢,php 7.0 unserialize 特别慢
thinkphp5.1 获取缓存cache(‘cache_name’)特别慢,php 7.0 unserialize 特别慢 场景: 项目中大量使用了缓存,本地运行非常快,二三百毫秒,部署到服务器后 一个表格请求就七八秒,最初猜想是数据库查询慢&am…...
【Linux】UNIX 术语中,换页与交换的区别和Linux 术语中,换页与交换的区别?
UNIX换页和交换的区别 在UNIX中,换页(Paging)是一种内存管理技术,用于在程序运行时动态地将其代码和数据从磁盘加载到内存中。当程序需要访问的页面不在内存中时,就会发生页错误(page error)&a…...
零基础学python之集合
文章目录 集合1、创建集合2、集合常见操作方法2、1 增加数据2、2 删除数据2、3 查找数据 3、总结 集合 目标 创建集合集合数据的特点集合的常见操作 1、创建集合 创建集合使用{}或set(), 但是如果要创建空集合只能使用set(),因为{}用来创建空字典。 …...
PromptScript:轻量级 DSL 脚本,加速多样化的 LLM 测试与验证
TL;DR 版本 PromptScript 是一个轻量级的 Prompt 调试用的 DSL (Yaml)脚本,以用于快速使用、构建 Prompt。 PromptScript 文档:https://framework.unitmesh.cc/prompt-script Why PromptScript ? 几个月前&…...
强化学习(Reinforcement Learning)与策略梯度(Policy Gradient)
写在前面:本篇博文的内容来自李宏毅机器学习课程与自己的理解,同时还参考了一些其他博客(懒得放链接)。博文的内容主要用于自己学习与记录。 1 强化学习的基本框架 强化学习(Reinforcement Learning, RL)主要由智能体(Agent/Actor)、环境(Environment)、…...
JUC之ForkJoin并行处理框架
ForkJoin并行处理框架 Fork/Join 它可以将一个大的任务拆分成多个子任务进行并行处理,最后将子任务结果合并成最后的计算结果,并进行输出。 类似于mapreduce 其实,在Java 8中引入的并行流计算,内部就是采用的ForkJoinPool来实现…...
【牛客面试必刷TOP101】Day8.BM33 二叉树的镜像和BM36 判断是不是平衡二叉树
作者简介:大家好,我是未央; 博客首页:未央.303 系列专栏:牛客面试必刷TOP101 每日一句:人的一生,可以有所作为的时机只有一次,那就是现在!!!&…...
CSS padding(填充)
CSS padding(填充)是一个简写属性,定义元素边框与元素内容之间的空间,即上下左右的内边距。 padding(填充) 当元素的 padding(填充)内边距被清除时,所释放的区域将会受到…...
C语言达到什么水平才能从事单片机工作
C语言达到什么水平才能从事单片机工作 从事单片机工作需要具备一定的C语言编程水平。以下是几个关键要点:基本C语言知识: 掌握C语言的基本语法、数据类型、运算符、流控制语句和函数等基本概念。最近很多小伙伴找我,说想要一些C语言学习资料&…...
Java架构师理解SAAS和多租户
目录 1 云服务的三种模式1.1 IaaS(基础设施即服务)1.2 PaaS(平台即服务)1.3 SaaS(软件即服务)1.4 区别与联系2 SaaS的概述2.1 Saas详解2.2 应用领域与行业前景2.3 Saas与传统软件对比3 多租户SaaS平台的数据库方案3.1 多租户是什么3.2 需求分析3.3 多租户的数据库方案分析…...
关于Java线程池相关面试题
【更多面试资料请加微信号:suns45】 https://flowus.cn/share/f6cd2cbe-627a-435f-a6e5-1395333f92e8 【FlowUs 息流】📣suns-Java资料 访问密码:【请加微信号:suns45】 ————线程相关的面试题———— 0:创建线…...
ExcelBDD Python指南
在Python里面支持BDD Excel BDD Tool Specification By ExcelBDD Method This tool is to get BDD test data from an excel file, its requirement specification is below The Essential of this approach is obtaining multiple sets of test data, so when combined with…...
基于深度学习的驾驶员疲劳监测系统的设计与实现
点击以下链接获取源码: https://download.csdn.net/download/qq_64505944/88421622?spm1001.2014.3001.5503 基于深度学习的驾驶员疲劳监测系统的设计与实现 1 绪论 在21世纪,各国的经济飞速发展,人民越来越富裕,道路上的汽车也逐…...
7.4.分块查找
一.分块查找的算法思想: 1.实例: 以上述图片的顺序表为例, 该顺序表的数据元素从整体来看是乱序的,但如果把这些数据元素分成一块一块的小区间, 第一个区间[0,1]索引上的数据元素都是小于等于10的, 第二…...
在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能
下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能,包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...
UDP(Echoserver)
网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法:netstat [选项] 功能:查看网络状态 常用选项: n 拒绝显示别名&#…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...
html-<abbr> 缩写或首字母缩略词
定义与作用 <abbr> 标签用于表示缩写或首字母缩略词,它可以帮助用户更好地理解缩写的含义,尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时,会显示一个提示框。 示例&#x…...
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...
【Go语言基础【12】】指针:声明、取地址、解引用
文章目录 零、概述:指针 vs. 引用(类比其他语言)一、指针基础概念二、指针声明与初始化三、指针操作符1. &:取地址(拿到内存地址)2. *:解引用(拿到值) 四、空指针&am…...
JS手写代码篇----使用Promise封装AJAX请求
15、使用Promise封装AJAX请求 promise就有reject和resolve了,就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...
「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案
在移动互联网营销竞争白热化的当下,推客小程序系统凭借其裂变传播、精准营销等特性,成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径,助力开发者打造具有市场竞争力的营销工具。 一、系统核心功能架构&…...
vue3 daterange正则踩坑
<el-form-item label"空置时间" prop"vacantTime"> <el-date-picker v-model"form.vacantTime" type"daterange" start-placeholder"开始日期" end-placeholder"结束日期" clearable :editable"fal…...
