开始
这一期我们来封装一个项目都能用到的网络请求库,话不多说直接奔主题,上代码!
开发环境
-
Windows
-
DevEco Studio NEXT Developer Preview2
-
HarmonyOS next Developer Preview2
-
java version "11.0.18" 2023-01-17 LTS
-
hdc 1.2.0a
-
手机:Mate 60Pro (HarmonyOS NEXT Developer Preview2)
使用
- 首先在module.json5中配置基础网络权限
"requestPermissions": [
{
"name": "ohos.permission.INTERNET",
}
]
- 定义baseURL基础地址常量
export const BASE_URL = 'https://----'
- 封装泛型工具类
export class Result<T> {
code: number = 0
msg: string = ""
data: T | null = null
}
- 封装一个公共的request方法来支持get/post/put/delete方法
const httpRequest = http.createHttp()
async function requestHttp<T>(url: string = "", method: http.RequestMethod = http.RequestMethod.GET, data?: object): Promise<T> {
let urlStr = BASE_URL + url
// 手动拼接
if (method === http.RequestMethod.GET) {
if (data && Object.keys(data).length) {
urlStr += "?" + Object.keys(data).map(key => {
if(data[key]){
return `${key}=${data[key]}`
}
return ""
}).join('&')
}
}
// 设置请求头
const config: http.HttpRequestOptions = {
header: {
'Content-Type': 'application/json',
"Authorization": AppStorage.Get(TOKEN_KEY) || ""
},
method,
readTimeout: 10000, // 超时时间
extraData: method === http.RequestMethod.GET ? "" : data
}
try {
const res = await httpRequest.request(urlStr, config)
if (res.responseCode === 401) {
promptAction.showToast({ message: 'token超时' })
AppStorage.Set(TOKEN_KEY, "") // 删除token
new UserSettingClass(getContext()).setUserToken("") // 清空首选项的token
router.replaceUrl({
url: 'pages/Login/Login'
})
return Promise.reject(new Error("token不存在或超时"))
}else if(res.responseCode === 404) {
promptAction.showToast({ message: '请求地址不正确' })
return Promise.reject(new Error('请求地址不正确'))
}
else {
const result = JSON.parse(res.result as string) as Result<T>
if (result.code === 200) {
// 执行成功
return result.data as T // 直接返回数据
}
else {
promptAction.showToast({ message: '服务器异常' })
return Promise.reject(new Error(result.msg))
}
}
} catch (error) {
promptAction.showToast({ message: error.message })
return Promise.reject(error)
}
finally {
httpRequest.destroy(); // 销毁请求
}
}
// 导出一个类的静态方法
export class Request {
static get<T>(url: string, data?: object): Promise<T> {
return requestHttp<T>(url, http.RequestMethod.GET, data)
}
static post<T>(url: string, data?: object): Promise<T> {
return requestHttp<T>(url, http.RequestMethod.POST, data)
}
static delete<T>(url: string, data?: object): Promise<T> {
return requestHttp<T>(url, http.RequestMethod.DELETE, data)
}
static put<T>(url: string, data?: object): Promise<T> {
return requestHttp<T>(url, http.RequestMethod.PUT, data)
}
}
- 封装接口,假设data先返回HomeDataModel,data是参数需要自己手动定义model,这里先用ParmsReq
export const getHomeData = (data: ParmsReq) => {
return Request.post<HomeDataModel>("/home/homeData", data)
}
- 使用接口,这里我用async await回调,parmsReq是参数,也可以用then 看个人习惯!
async getHomeData() {
try {
const homeData = await getHomeData(this.parmsReq)
}catch (error) {
} finally {
}
- 好了,以上就是封装和使用,就这样简单,开箱即用,建议结合自己的项目封装 还有统一的dialog、提示、占位图、网络异常图,也可以自己在上层做一个RequestStatus做转发!
总结
- 封装请求-拼接基础地址-传入参数
- 解构返回的数据-判断状态
- 200 认为成功直接返回data数据
- 200以外 401 认为是token超时
- 500认为是服务器错误
- 最后暴露一个类的四个静态方法 可以方便的调用 get/put/delete/post
本文正在参加华为鸿蒙有奖征文征文活动