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世纪,各国的经济飞速发展,人民越来越富裕,道路上的汽车也逐…...
CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型
CVPR 2025 | MIMO:支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题:MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者:Yanyuan Chen, Dexuan Xu, Yu Hu…...
逻辑回归:给不确定性划界的分类大师
想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...
Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
FastAPI 教程:从入门到实践
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,支持 Python 3.6。它基于标准 Python 类型提示,易于学习且功能强大。以下是一个完整的 FastAPI 入门教程,涵盖从环境搭建到创建并运行一个简单的…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...
HarmonyOS运动开发:如何用mpchart绘制运动配速图表
##鸿蒙核心技术##运动开发##Sensor Service Kit(传感器服务)# 前言 在运动类应用中,运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据,如配速、距离、卡路里消耗等,用户可以更清晰…...
针对药品仓库的效期管理问题,如何利用WMS系统“破局”
案例: 某医药分销企业,主要经营各类药品的批发与零售。由于药品的特殊性,效期管理至关重要,但该企业一直面临效期问题的困扰。在未使用WMS系统之前,其药品入库、存储、出库等环节的效期管理主要依赖人工记录与检查。库…...
使用 uv 工具快速部署并管理 vLLM 推理环境
uv:现代 Python 项目管理的高效助手 uv:Rust 驱动的 Python 包管理新时代 在部署大语言模型(LLM)推理服务时,vLLM 是一个备受关注的方案,具备高吞吐、低延迟和对 OpenAI API 的良好兼容性。为了提高部署效…...
Redis专题-实战篇一-基于Session和Redis实现登录业务
GitHub项目地址:https://github.com/whltaoin/redisLearningProject_hm-dianping 基于Session实现登录业务功能提交版本码:e34399f 基于Redis实现登录业务提交版本码:60bf740 一、导入黑马点评后端项目 项目架构图 1. 前期阶段2. 后续阶段导…...
论文阅读笔记——Large Language Models Are Zero-Shot Fuzzers
TitanFuzz 论文 深度学习库(TensorFlow 和 Pytorch)中的 bug 对下游任务系统是重要的,保障安全性和有效性。在深度学习(DL)库的模糊测试领域,直接生成满足输入语言(例如 Python )语法/语义和张量计算的DL A…...
