HarmonyOS开发5.0【封装request泛型方法】axios

一 准备工作

1. 先开启一下虚拟机的权限

src/main/module.json5 打开module.json5在15~19行 进行配置网络权限

1

2. 在终端下载安装一下 ohpm install @ohos/axios

复制 粘贴进去回车就行

2

3. 这样显示就是安装好了

如果导入不行就关了重新启动

3

二 创建一个ETS文件,利用静态的泛型方法对axios模块进行统一请求封装(方法名:reqeust,兼容get和post)

axios.reqeust()方法中请求参数提炼和响应泛型提炼

import axios, { AxiosResponse, AxiosError, AxiosRequestConfig } from'@ohos/axios'
import { iResponseModel } from '../models/datamodel'// 1. 准备一个axios的对象实例,同时设置好baseUrl
const req = axios.create({baseURL: 'https://juejin.cn/'
})export class HdHttp {/*method:表示服务器的请求方法,Get,POST,PUT,Deleteurl:代表的是服务器的url路径(不包含基本域名地址) ,例如:user/1379256207678675* paramsOrData:请求传参,可选** T:代表的是服务器响应数据中的 data这个属性的类型* */static async request<T>(method: string, url: string, paramsOrData?: object) {try {//   1. 使用req来发送请求let reqConfig: AxiosRequestConfig = {method: method,url: url, //是请求接口的url路径部分,并且不带有/}// 2. 分请求类型来决定传参参数是parmas还是dataif (method == 'GET') {reqConfig.params = paramsOrData} else {reqConfig.data = paramsOrData}let res: AxiosResponse<iResponseModel<T>> = await req.request(reqConfig)//   3. 返回结果(返回的是服务器的响应报文体的数据)return res.data} catch (err) {//  当服务器的http状态码为非200,就会执行catchlet errObj: AxiosError = errreturn Promise.reject(errObj.message) // 外面使用者使用try{}catch(err){}}}
}

三 增加toke携带和处理非10000的逻辑状态码的响应结果(接口响应正常,但是有逻辑异常,比如用户名或者密码错误)

import axios, { AxiosResponse, AxiosError, AxiosRequestConfig } from '@ohos/axios'
import { iLoginUserModel, iResponseModel } from '../models/datamodel'
import { promptAction } from '@kit.ArkUI'// 1. 准备一个axios的对象实例,同时设置好baseUrl
const req = axios.create({baseURL: 'https://juejin.cn/'
})export class HdHttp {/*method:表示服务器的请求方法,Get,POST,PUT,Deleteurl:代表的是服务器的url路径(不包含基本域名地址) ,例如:user/1379256207678675* paramsOrData:请求传参,可选** T:代表的是服务器响应数据中的 data这个属性的类型* */static async request<T>(method: string, url: string, paramsOrData?: object) {try {//   1. 使用req来发送请求let reqConfig: AxiosRequestConfig = {method: method,url: url, //是请求接口的url路径部分,并且不带有/}// 2. 分请求类型来决定传参参数是parmas还是dataif (method == 'GET') {reqConfig.params = paramsOrData} else {reqConfig.data = paramsOrData}// 3. 在请求前在header中携带token// 获取tokenlet user = AppStorage.get<iLoginUserModel>('user')if (user && user.token) {reqConfig.headers = {'Authorization': `Bearer ${user.token}`}}let res: AxiosResponse<iResponseModel<T>> = await req.request(reqConfig)// 4. 处理服务器响应体中的code值为非10000的情况if (res.data.code != 10000) {//  将服务器的逻辑问题信息提示给用户promptAction.showToast({ message: res.data.message })return Promise.reject(res.data.message)  //传递给外部调用者的 catch()中的信息}//   3. 返回结果(返回的是服务器的响应报文体的数据)return res.data} catch (err) {//  当服务器的http状态码为非200,就会执行catchlet errObj: AxiosError = errreturn Promise.reject(errObj.message) //传递给外部调用者的 catch()中的信息 外面使用者使用try{}catch(err){}}}
}

四 在try{}catch(err){}的catch里面处理状态码为401的时跳转到登录页面,其他状态码时提示用户 errObj.response?.status == 401

import { promptAction, router } from '@kit.ArkUI'
import axios, { AxiosResponse, AxiosError } from '@ohos/axios'
import { iLoginUserModel, iResponseModel } from '../models/datamodel'
import { HdHttp } from '../utils/request'interface iReqBody {username: stringpassword: string
}@Entry
@Component
struct LoginPage {@State username: string = 'yu123'@State password: string = 'yu123456'@State isAgree: boolean = false@State islogin: boolean = false// 负责登录async login() {// 1. 参数合法性检查/** ● 能对用户名和密码文本框做非空验证处理● 对用户协议勾选做验证处理* */if (this.username == '' || this.password == '') {return promptAction.showToast({ message: '用户名和密码必填' })}if (!this.isAgree) {promptAction.showToast({ message: '请先勾选协议' })this.isAgree = truereturn}// 2. axios请求服务器接口this.islogin = truetry {let reqBody = new Object({username: this.username,password: this.password})let res = await HdHttp.request<iLoginUserModel>('POST', 'hm/login', reqBody)this.islogin = false// 3. 处理服务器响应回来的报文体的数据//   3.1 判断服务器响应体中的code==10000的时候才保存数据,否则提示用户响应体中的message// if (res.data.code != 10000) {//   return promptAction.showToast({ message: res.data.message })// }// 3.2 将服务器响应回来的数据保存到AppStroage中,保存的数据类型是iLoginUserModelAppStorage.setOrCreate('user', res.data)// 4. 跳转到首页router.replaceUrl({ url: 'pages/Index' })} catch (err) {this.islogin = false// 将来服务器的状态码是非200的,就会自动触发catchlet errObj: AxiosError = err //最终将err大错误对象,转为AxiosErrorAlertDialog.show({ message: errObj.message }) //最后提示给用户的是message字符串}}build() {Column() {// logoColumn({ space: 10 }) {Image($r('app.media.icon')).height(55).aspectRatio(1)}.margin({ top: 170 })//  登录区域Column({ space: 20 }) {TextInput({ text: $$this.username }).backgroundColor(Color.White).width('90%').borderRadius(0)TextInput({ text: $$this.password }).type(InputType.Password).backgroundColor(Color.White).width('90%')Row() {Checkbox().select(this.isAgree).selectedColor('#FA6D1D').onChange(value => {this.isAgree = value})Text('已阅读并同意').fontSize(14).fontColor($r('app.color.ih_gray_color')).padding({ right: 4 })Text('用户协议').fontSize(14).padding({ right: 4 })Text('和').fontSize(14).fontColor($r('app.color.ih_gray_color')).padding({ right: 4 })Text('隐私政策').fontSize(14).onClick(() => {router.pushUrl({url: 'pages/PreviewWebPage'})})}.width('90%')Button({ type: ButtonType.Normal }) {Row() {if (this.islogin) {LoadingProgress().height(28).aspectRatio(1).color(Color.White)}Text('登录')}}.borderRadius(4).width(328).height(45).fontColor(Color.White).linearGradient({angle: 135,colors: [['#FCA21C', 0],['#FA6D1D', 1]]}).onClick(() => {this.login()})}.margin({ top: 50 })}.width('100%').height('100%')}
}
import axios, { AxiosResponse, AxiosError, AxiosRequestConfig } from '@ohos/axios'
import { iLoginUserModel, iResponseModel } from '../models/datamodel'
import { promptAction, router } from '@kit.ArkUI'// 1. 准备一个axios的对象实例,同时设置好baseUrl
const req = axios.create({baseURL: 'https://juejin.cn/'
})export class HdHttp {/*method:表示服务器的请求方法,Get,POST,PUT,Deleteurl:代表的是服务器的url路径(不包含基本域名地址) ,例如:user/1379256207678675* paramsOrData:请求传参,可选** T:代表的是服务器响应数据中的 data这个属性的类型* */static async request<T>(method: string, url: string, paramsOrData?: object) {try {//   1. 使用req来发送请求let reqConfig: AxiosRequestConfig = {method: method,url: url, //是请求接口的url路径部分,并且不带有/}// 2. 分请求类型来决定传参参数是parmas还是dataif (method == 'GET') {reqConfig.params = paramsOrData} else {reqConfig.data = paramsOrData}// 3. 在请求前在header中携带token// 获取tokenlet user = AppStorage.get<iLoginUserModel>('user')if (user && user.token) {reqConfig.headers = {'Authorization': `Bearer ${user.token}`}}let res: AxiosResponse<iResponseModel<T>> = await req.request(reqConfig)// 4. 处理服务器响应体中的code值为非10000的情况if (res.data.code != 10000) {//  将服务器的逻辑问题信息提示给用户promptAction.showToast({ message: res.data.message })return Promise.reject(res.data.message) //传递给外部调用者的 catch()中的信息}//   3. 返回结果(返回的是服务器的响应报文体的数据)return res.data} catch (err) {//  当服务器的http状态码为非200,就会执行catchlet errObj: AxiosError = err// 判断服务器的响应状态码如果是401,表示token失效,此时应该提示用户和跳转到登录页面if (errObj.response?.status == 401) {promptAction.showToast({ message: '登录已失效,请重新登录' })router.replaceUrl({ url: 'pages/LoginPage' })} else {//  提示用户是什么错误即可promptAction.showToast({ message: '网络异常:' + errObj.message })}// AlertDialog.show({ message: 'err:' + JSON.stringify(errObj.response?.status, null, 2) })return Promise.reject(errObj.message) //传递给外部调用者的 catch()中的信息 外面使用者使用try{}catch(err){}}}
}

五 提炼单独的POST < T > 和 GET< T >来简化对上一步封装好的reqeust方法的调用

封装完成 完整版

import axios, { AxiosResponse, AxiosError, AxiosRequestConfig } from '@ohos/axios'
import { iLoginUserModel, iResponseModel } from '../models/datamodel'
import { promptAction, router } from '@kit.ArkUI'// 1. 准备一个axios的对象实例,同时设置好baseUrl
const req = axios.create({baseURL: 'https://juejin.cn/'
})export class HdHttp {// 这个方法给外面专门做get请求调用的static async Get<T>(url: string, paramsOrData?: object) {return await HdHttp.request<T>('GET', url, paramsOrData)}// 这个方法给外面专门做post请求调用的static async Post<T>(url: string, paramsOrData?: object) {return await HdHttp.request<T>('POST', url, paramsOrData)}/*method:表示服务器的请求方法,Get,POST,PUT,Deleteurl:代表的是服务器的url路径(不包含基本域名地址) ,例如:user/1379256207678675* paramsOrData:请求传参,可选** T:代表的是服务器响应数据中的 data这个属性的类型* */private static async request<T>(method: string, url: string, paramsOrData?: object) {try {//   1. 使用req来发送请求let reqConfig: AxiosRequestConfig = {method: method,url: url, //是请求接口的url路径部分,并且不带有/}// 2. 分请求类型来决定传参参数是parmas还是dataif (method == 'GET') {reqConfig.params = paramsOrData} else {reqConfig.data = paramsOrData}// 3. 在请求前在header中携带token// 获取tokenlet user = AppStorage.get<iLoginUserModel>('user')if (user && user.token) {reqConfig.headers = {'Authorization': `Bearer ${user.token}`}}let res: AxiosResponse<iResponseModel<T>> = await req.request(reqConfig)// 4. 处理服务器响应体中的code值为非10000的情况if (res.data.code != 10000) {//  将服务器的逻辑问题信息提示给用户promptAction.showToast({ message: res.data.message })return Promise.reject(res.data.message) //传递给外部调用者的 catch()中的信息}//   3. 返回结果(返回的是服务器的响应报文体的数据)return res.data} catch (err) {//  当服务器的http状态码为非200,就会执行catchlet errObj: AxiosError = err// 判断服务器的响应状态码如果是401,表示token失效,此时应该提示用户和跳转到登录页面if (errObj.response?.status == 401) {promptAction.showToast({ message: '登录已失效,请重新登录' })router.replaceUrl({ url: 'pages/LoginPage' })} else {//  提示用户是什么错误即可promptAction.showToast({ message: '网络异常:' + errObj.message })}// AlertDialog.show({ message: 'err:' + JSON.stringify(errObj.response?.status, null, 2) })return Promise.reject(errObj.message) //传递给外部调用者的 catch()中的信息 外面使用者使用try{}catch(err){}}}
}

总结

以上是我在项目中的用到的关于 axios 的一些封装方法。

以上就是本篇文章所带来的鸿蒙开发中一小部分技术讲解;想要学习完整的鸿蒙全栈技术。可以在结尾找我可全部拿到!
下面是鸿蒙的完整学习路线,展示如下:
1

除此之外,根据这个学习鸿蒙全栈学习路线,也附带一整套完整的学习【文档+视频】,内容包含如下

内容包含了:(ArkTS、ArkUI、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、鸿蒙南向开发、鸿蒙项目实战)等技术知识点。帮助大家在学习鸿蒙路上快速成长!

鸿蒙【北向应用开发+南向系统层开发】文档

鸿蒙【基础+实战项目】视频

鸿蒙面经

2

为了避免大家在学习过程中产生更多的时间成本,对比我把以上内容全部放在了↓↓↓想要的可以自拿喔!谢谢大家观看!
3

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/54149.shtml

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

相关文章

编译运行 webAssembly(wasm)

环境准备&#xff1a; lunix下docker 参考https://hub.docker.com/r/emscripten/emsdk 拉编译环境 docker pull emscripten/emsdk 编译 随便找个目录&#xff0c;敲下面命令&#xff0c;编译一个webAssembly 程序 # create helloworld.cpp cat << EOF > hellowo…

Python基础语法(1)上

常量和表达式 我们可以把 Python 当成一个计算器&#xff0c;来进行一些算术运算。 print(1 2 - 3) print(1 2 * 3) print(1 2 / 3) 这里我们可能会有疑问&#xff0c;为什么不是1.6666666666666667呢&#xff1f; 其实在编程中&#xff0c;一般没有“四舍五入”这样的规则…

Qt-QPushButton按钮类控件(22)

目录 描述 使用 给按钮添加图片 给按钮添加快捷键 添加槽函数 添加快捷键 添加组合键 开启鼠标的连发功能 描述 经过上面的一些介绍&#xff0c;我们也尝试的使用过了这个控件&#xff0c;接下来我们就要详细介绍这些比较重要的控件了 使用 给按钮添加图片 我们创建…

Java高级Day41-反射入门

115.反射 反射机制 1.根据配置文件re.properties指定信息&#xff0c;创建Cat对象并调用hi方法 SuppressWarnings({"all"}) public class ReflectionQuestion {public static void main(String[] args) throws IOException {//根据配置文件 re.properties 指定信息…

带你0到1之QT编程:十一、掌握Containers容器艺术,一网打尽开发利器

此为QT编程的第十一谈&#xff01;关注我&#xff0c;带你快速学习QT编程的学习路线&#xff01; 每一篇的技术点都是很很重要&#xff01;很重要&#xff01;很重要&#xff01;但不冗余&#xff01; 我们通常采取总-分-总和生活化的讲解方式来阐述一个知识点&#xff01; …

【CSS in Depth 2 精译_031】5.3 Grid 网格布局的两种替代语法

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 第一章 层叠、优先级与继承&#xff08;已完结&#xff09; 1.1 层叠1.2 继承1.3 特殊值1.4 简写属性1.5 CSS 渐进式增强技术1.6 本章小结 第二章 相对单位&#xff08;已完结&#xff09; 2.1 相对…

计算机毕业设计 扶贫助农系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

浅谈人工智能之基于ollama本地大模型结合本地知识库搭建智能客服

浅谈人工智能之基于ollama本地大模型结合本地知识库搭建智能客服 摘要 随着人工智能技术的飞速发展,基于大型语言模型(LLMs)的智能客服系统逐渐成为提升企业服务质量和效率的关键工具。然而,对于注重数据隐私和安全的企业而言,使用云服务可能会引发数据泄露的风险。因此…

基于微信小程序的图书馆预约占座系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 基于微信小程序JavaSpringBootVueMySQL的图…

(k8s)kubernetes 挂载 minio csi 的方式(pod挂载pvc存在csi驱动问题,挂载不上)

一、安装Minio&#xff08;Minio分布式集群搭建部署_minio集群最少几台-CSDN博客&#xff09; 生成accessKeyID和secretAccessKey&#xff1a; 二、安装csi-s3插件(在k8s集群上) 首先我们把插件的yaml文件都下载下来&#xff0c;为了保证版本测试的一致性&#xff0c;我们下载…

FreeRTOS—任务通知

一&#xff0c;概念介绍 队列、信号量、事件组等IPC技术都需要创建一个中间对象进程之间通过这些中间对象进行通讯或同步。创建对象就需要分配内存&#xff0c;占用一定内存。 二&#xff0c;任务通知的特点&#xff1a; 一个任务或ISR向另外一个指定的任务发送通知&#xff0c…

浅谈树型结构——树

文章目录 一、什么是树&#xff1f;二、树的特点三、树的概念四、树的表示形式五、树的应用 一、什么是树&#xff1f; 树是一种 非线性 的数据结构&#xff0c;是树型结构。是一个由n个有限结点组成的一个具有层次关系的集合&#xff0c;这种集合因为看起来像一颗倒挂的树&am…

波克城市 x NebulaGraph|高效数据血缘系统在游戏领域的构建实战

关于波克城市和作者‍‍ 波克城市&#xff0c;一家专注于研发精品休闲游戏的全球化公司&#xff0c;连续七年入选中国互联网综合实力百强&#xff0c;2023 年位列 17 位。波克城市旗下拥有《捕鱼达人》《猫咪公寓2》等精品休闲游戏&#xff0c;全球注册用户超 5 亿&#xff0c;…

借老系统重构我准备写个迷你版apiFox

前段时间一直在忙公司老系统重构的方案设计&#xff0c;其中最大的重构点就是前后端分离。为了加快前后端协同开发和对接的工作效率&#xff0c;我决定写一个公司内部使用的迷你版的apiFox。 文章目录 有现成的工具为啥不用现有成熟方案初步成果展示下一步计划 有现成的工具为啥…

Kafka+PostgreSql,构建一个总线服务

之前开发的系统&#xff0c;用到了RabbitMQ和SQL Server作为总线服务的传输层和存储层&#xff0c;最近一直在看Kafka和PostgreSql相关的知识&#xff0c;想着是不是可以把服务总线的技术栈切换到这个上面。今天花了点时间试了试&#xff0c;过程还是比较顺利的&#xff0c;后续…

华为CNA VRM搭建(使用vmware worfstartion搭建)

创建虚拟机&#xff1a; 自定义→高级 选择硬件兼容性&#xff1a;默认安装版本&#xff0c;如果未来想要将此虚拟机安装到其他电脑&#xff0c;其他电脑版本过低&#xff0c;此时可以向下兼容&#xff0c;这里我们默认版本 稍后安装操作系统&#xff1a; CNA采用Euler OS系统…

MySQL练手题--体育馆的人流量(困难)

一、准备工作 Create table If Not Exists Stadium (id int, visit_date DATE NULL, people int); Truncate table Stadium; insert into Stadium (id, visit_date, people) values (1, 2017-01-01, 10); insert into Stadium (id, visit_date, people) values (2, 2017-01-02…

springboot luttuc redis 集成protobuf,手动序列化反序列化

前置需知&#xff1a; 1.本文章和网上大部分博客配置不太一样&#xff0c;各位看官要分析一下自己的需求。集成protobuf 本文章主要是手动调用protobuf的序列化方法&#xff0c;而不是交由springboot 去做&#xff0c;会偏向原生java 使用方式 2.由于为了和公司其他的项目达成…

HTML + CSS - 网页布局之一般布局浮动布局

1. 一般布局 1.1 一般布局相关参数 元素内容常常可以想像为放在一个盒子里&#xff0c;然后在周边加上内边距&#xff0c;边框和外边距&#xff0c;是盒子模型 默认一个块级区域会填充父类所有的行向空间&#xff0c;并且沿着块伸长容纳其内容&#xff0c;可以为块状体设置某…

实习项目|苍穹外卖|day10

Spring Task cron 表达式 入门案例 订单状态定时处理 通知用户支付&#xff01;通知商家完成订单&#xff01; Scheduled(cron "0 0/1 * * * ? ")public void processTimeoutOrder(){log.info("定时处理超时订单: {}", LocalDateTime.now());//答案是…