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世纪,各国的经济飞速发展,人民越来越富裕,道路上的汽车也逐…...
Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...
安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲
文章目录 前言第一部分:体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分:体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...
Go 并发编程基础:通道(Channel)的使用
在 Go 中,Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式,用于在多个 Goroutine 之间传递数据,从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...
C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)
名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...
STM32HAL库USART源代码解析及应用
STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...
省略号和可变参数模板
本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...
关于uniapp展示PDF的解决方案
在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项: 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库: npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...
从面试角度回答Android中ContentProvider启动原理
Android中ContentProvider原理的面试角度解析,分为已启动和未启动两种场景: 一、ContentProvider已启动的情况 1. 核心流程 触发条件:当其他组件(如Activity、Service)通过ContentR…...
在 Spring Boot 中使用 JSP
jsp? 好多年没用了。重新整一下 还费了点时间,记录一下。 项目结构: pom: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://ww…...
基于鸿蒙(HarmonyOS5)的打车小程序
1. 开发环境准备 安装DevEco Studio (鸿蒙官方IDE)配置HarmonyOS SDK申请开发者账号和必要的API密钥 2. 项目结构设计 ├── entry │ ├── src │ │ ├── main │ │ │ ├── ets │ │ │ │ ├── pages │ │ │ │ │ ├── H…...
