鴻蒙【ArkTS】封裝數(shù)據(jù)請(qǐng)求HTTP 使用裝飾器進(jìn)行配置化引入接口
官方API文檔:數(shù)據(jù)請(qǐng)求HTTP
實(shí)現(xiàn)步驟:
一、統(tǒng)一接口請(qǐng)求結(jié)果
export class ApiResult {
code : string
msg ?: string
data ?: any
}
二、網(wǎng)絡(luò)請(qǐng)求配置類
/**
* <pre>
* @desc : 網(wǎng)絡(luò)請(qǐng)求配置
* </pre>
*/
export interface RequestOptions {
/**
* Request url.
*/
url?: string;
/**
* Request method.
*/
method?: RequestMethod; // default is GET
/**
* Additional data of the request.
* extraData can be a string or an Object (API 6) or an ArrayBuffer(API 8).
*/
extraData?: string | Object | ArrayBuffer;
/**
* Request url queryParams .
*/
queryParams ?: Record<string, string>;
/**
* HTTP request header.
*/
header?: Object; // default is 'content-type': 'application/json'
}
export enum RequestMethod {
OPTIONS = "OPTIONS",
GET = "GET",
HEAD = "HEAD",
POST = "POST",
PUT = "PUT",
DELETE = "DELETE",
TRACE = "TRACE",
CONNECT = "CONNECT"
}
三、網(wǎng)絡(luò)請(qǐng)求核心類 引用官方Api
import http from '@ohos.net.http';
import { RequestOptions } from './RequestOptions';
import { ApiResult } from '../ApiResult/ApiResult';
// 引入彈窗
import PreferenceUtil from '../../utils/PreferenceUtil'
import promptAction from '@ohos.promptAction';
import { LoadingProgressDialog } from '../../utils/LoadingProgressDialog';
import router from '@ohos.router';
/**
* Http請(qǐng)求器
*/
export class HttpCore {
loadingDialog: CustomDialogController = new CustomDialogController({
builder: LoadingProgressDialog(),
alignment:DialogAlignment.Center,
autoCancel: true,
customStyle: true
});
/**
* 發(fā)送請(qǐng)求
* @param requestOption
* @returns Promise
*/
request(requestOptions: RequestOptions): Promise<ApiResult> {
let p = new Promise<ApiResult>(async (resolve, reject) => {
// 每一個(gè)httpRequest對(duì)應(yīng)一個(gè)HTTP請(qǐng)求任務(wù),不可復(fù)用
let httpRequest = http.createHttp();
let token : string = await getToken();
let promise = httpRequest.request(requestOptions.url, {
method: requestOptions.method,
connectTimeout: 60000,
readTimeout: 60000,
header:{
'Content-Type': 'application/json',
'token': token,
'client_type': 'HarmonyOS'
},
extraData: requestOptions.extraData
});
promise.then((data) => {
//TODO:此處補(bǔ)充數(shù)據(jù)拆包的操作
let resultObj = JSON.parse(data.result.toString());
//彈窗提示接口返回msg
setTimeout(() => {
promptAction.showToast({
message: resultObj.msg
})
}, 500);
//如果業(yè)務(wù)碼為20000 則返回ApiReslut
if (resultObj.code == 20000) {
console.log(JSON.stringify(resultObj))
resolve(resultObj);
}
if (resultObj.code == 0){
router.replaceUrl({
url: "pages/MainPage/Login"
}).then(() => {
console.log('router successful')
}).catch(err => {
console.log('router err')
})
}
//如果返回?cái)?shù)據(jù)包含token信息 則刷新token
if (resultObj.token != undefined) {
PreferenceUtil.putPreference('token',resultObj.token)
}
}).catch((err) => {
//這里做全局異常統(tǒng)一處理 根據(jù)Http狀態(tài)碼做出處理
console.info('error:' + JSON.stringify(err));
reject(err);
});
httpRequest.destroy();
})
return p;
}
}
async function getToken(): Promise<string> {
return new Promise<string>(async (resolve, reject) => {
try {
const data = await PreferenceUtil.getPreference('token');
if (typeof data === 'string') {
resolve(data);
} else {
reject(new Error('Invalid token'));
}
} catch (err) {
reject(err);
}
});
}
export const httpCore = new HttpCore();
四、導(dǎo)出對(duì)外工具類
import { RequestMethod, RequestOptions } from './RequestOptions';
import { httpCore } from './HttpCore';
import { ApiResult } from '../ApiResult/ApiResult';
/**
* <pre>
* @desc : 對(duì)外工具包
* </pre>
*/
export class HttpUtil {
private static mInstance: HttpUtil;
// 防止實(shí)例化
private constructor() {
}
static getInstance(): HttpUtil {
if (!HttpUtil.mInstance) {
HttpUtil.mInstance = new HttpUtil();
}
return HttpUtil.mInstance;
}
request (option: RequestOptions): Promise<ApiResult> {
return httpCore.request(option);
}
/**
* 封裝Post網(wǎng)絡(luò)請(qǐng)求
* @param option
* @returns
*/
Post(option:RequestOptions){
if(option != null){
option.method = RequestMethod.POST
}
return this.request(option);
}
/**
* 封裝Get網(wǎng)絡(luò)請(qǐng)求
* @param option
* @returns
*/
Get(option:RequestOptions){
if(option != null){
option.method = RequestMethod.GET
}
return this.request(option);
}
}
export const httpUtil = HttpUtil.getInstance();
五、利用裝飾器實(shí)現(xiàn)AOP效果
import { ApiResult } from '../ApiResult/ApiResult';
import { httpUtil } from '../Http/HttpUtil';
import { RequestOptions } from '../Http/RequestOptions';
/**
* 利用Map保存參數(shù)和值的映射關(guān)系 為避免參數(shù)名及方法名重復(fù) 采用組合Key的方法
*/
type FunParamMapKey = {
target: Object; //所在類
methodName: string; //所在方法
index: number; //參數(shù)名索引值
}
let funParamMap = new Map<string, string>();
// @Get注解 拿到url 從函數(shù)的@Param拿到參數(shù)名及參數(shù)值 利用HttpUtil進(jìn)行網(wǎng)絡(luò)請(qǐng)求
//Get 需要拼接URl
export function Get(url: string) {
return function (target: any, methodName: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
let URL: string = url;
let options: RequestOptions = {
url: URL,
queryParams: {}
};
descriptor.value = async function (...args: any[]) {
//對(duì)于方法中的每一個(gè)(methodName,arg)遍歷加入到網(wǎng)絡(luò)請(qǐng)求配置中
args.forEach((arg, index) => {
// 通過(guò)已知的信息構(gòu)造組合Key對(duì)象
let obj: FunParamMapKey = { target: target, methodName: methodName, index: index };
// 通過(guò)組合Key(通過(guò)對(duì)內(nèi)容的比較而不是值 節(jié)省內(nèi)存)從內(nèi)存map中獲取@Param修飾的內(nèi)容
let paramName = funParamMap[JSON.stringify(obj)];
// 將正確的參數(shù)名及值添加至網(wǎng)絡(luò)請(qǐng)求參數(shù)中
if (typeof paramName !== 'undefined') {
if (typeof arg === 'string' || typeof arg === 'object' || arg instanceof ArrayBuffer || typeof arg === 'number') {
options.queryParams[paramName] = arg
} else {
console.log('參數(shù)類型不對(duì)')
throw new Error(`Invalid parameter type at index ${index}.`);
}
}
});
//拼接請(qǐng)求參數(shù)
const urlParams = Object.keys(options.queryParams).map(key => `${key}=${options.queryParams[key]}`).join('&')
console.log('urlParams:', urlParams)
if (URL.includes("?")) {
options.url = `${URL}${urlParams}`
} else {
options.url = `${URL}?${urlParams}`
}
const p = new Promise<ApiResult>((resolve, reject) => {
httpUtil.Get(options).then((response) => {
const result: ApiResult = response;
resolve(result);
}).catch((error) => {
reject(error);
});
});
return await p;
};
};
}
// @Post注解 拿到url 從函數(shù)的@Param拿到參數(shù)名及參數(shù)值 利用HttpUtil進(jìn)行Post網(wǎng)絡(luò)請(qǐng)求
export function Post(url: string) {
return function (target: any, methodName: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
let options: RequestOptions = {
url: url,
extraData: {}
};
descriptor.value = async function (...args: any[]) {
//對(duì)于方法中的每一個(gè)(methodName,arg)遍歷加入到網(wǎng)絡(luò)請(qǐng)求配置中
args.forEach((arg, index) => {
console.log("參數(shù)值",JSON.stringify(arg))
// 通過(guò)已知的信息構(gòu)造組合Key對(duì)象
let obj: FunParamMapKey = { target: target, methodName: methodName, index: index };
// 通過(guò)組合Key(通過(guò)對(duì)內(nèi)容的比較而不是值 節(jié)省內(nèi)存)從內(nèi)存map中獲取@Param修飾的內(nèi)容
let paramName = funParamMap[JSON.stringify(obj)];
console.log("參數(shù)名:",paramName)
// 將正確的參數(shù)名及值添加至網(wǎng)絡(luò)請(qǐng)求參數(shù)中
if (typeof paramName !== 'undefined') {
if (typeof arg === 'string' || typeof arg === 'object' || arg instanceof ArrayBuffer) {
options.extraData[paramName] = arg;
} else {
throw new Error(`Invalid parameter type at index ${index}.`);
}
}else {
//如果獲取不到形參名 及未被@Param標(biāo)記 并且參數(shù)的類型是對(duì)象
if (typeof arg === 'object') {
options.extraData = JSON.stringify(arg)
}
}
});
console.log('extraData', JSON.stringify(options.extraData))
const p = new Promise<ApiResult>((resolve, reject) => {
httpUtil.Post(options).then((response) => {
const result: ApiResult = response;
resolve(result);
}).catch((error) => {
reject(error);
});
});
return await p;
};
};
}
/**
* @Param 注解將想要獲取的Param添加至內(nèi)存Map中
* @param paramName
* @returns
*/
export function Param(paramName: string) {
return function (target: any, methodName: string, parameterIndex: number) {
let obj: FunParamMapKey = { target: target, methodName: methodName, index: parameterIndex };
funParamMap[JSON.stringify(obj)] = paramName;
};
}
使用示例:
import{Post, Param} from './aop/aop'
import { ApiResult } from './ApiResult/ApiResult';
export class LoginApi {
@Post("http://localhost:8080/login")
//自定義@Param 作用:獲取形參 便于映射到extraData
login(@Param("username") username: string, @Param("password") password: string):Promise<ApiResult> {
return
}
}
export const loginApi = new LoginApi();
import{Post,Get, Param} from './aop/aop'
import { ApiResult } from './ApiResult/ApiResult';
export class MenuApi {
@Get("http://localhost:8080/api/menu/getMenuTree")
getMenuTree():Promise<ApiResult> {
return
}
@Get("http://localhost:8080/api/menu/getPermTree")
getPermsSelectTree():Promise<ApiResult> {
return
}
//@Get中的@Param 可以將形參拼接到URl中
@Get("http://localhost:8080/api/menu/get")
getMenuById(@Param("Id") id : number):Promise<ApiResult> {
return
}
}
export const menuApi = new MenuApi();
import { RoleModel } from '../models/RoleModel';
import{Post,Get, Param} from './aop/aop'
import { ApiResult } from './ApiResult/ApiResult';
export class RoleApi{
/**
* 獲取所有角色
* @returns
*/
@Get("http://localhost:8080/api/role/getAllRole")
getAllRole():Promise<ApiResult> {
return
}
//可以直接Post對(duì)象
@Post("http://localhost:8080/api/role/updateRole")
updateRole(role : RoleModel):Promise<ApiResult> {
return
}
}
export const roleApi = new RoleApi();
文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-855850.html
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-855850.html
到了這里,關(guān)于鴻蒙【ArkTS】封裝數(shù)據(jù)請(qǐng)求HTTP 使用裝飾器進(jìn)行配置化引入接口的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!