Demo地址:https://gitee.com/hyhe/httpLibraryDemo.git
加解密、https認(rèn)證在HarmonyOS HTTP網(wǎng)絡(luò)請(qǐng)求(二)中做處理
一、框架說(shuō)明
http請(qǐng)求框架說(shuō)明.png
1. 功能說(shuō)明
DecryptionResponseParam: 數(shù)據(jù)解密處理 待實(shí)現(xiàn)
EncryptionRequestParam: 數(shù)據(jù)加密處理 待實(shí)現(xiàn)
PrettyPrint: 日志打印處理
RequestApi: api列表
RequestAuthenHandler: 認(rèn)證處理 待實(shí)現(xiàn)
RequestConfiguration: 配置RequestOption
HttpManager: 請(qǐng)求管理類
RequestImplement: 請(qǐng)求實(shí)現(xiàn)類
RequestMethod: 請(qǐng)求方法枚舉
RequestOption: 自定義RequestOption類
RequestTools: http模塊工具類
ResponseHandler: 請(qǐng)求結(jié)果處理類
ResponseModel: 最終返回業(yè)務(wù)層數(shù)據(jù)模型
二买鸽、核心類說(shuō)明
1. 請(qǐng)求RequestOption類
export class RequestOption {
/**
* 請(qǐng)求host
* 如果特定接口需要更換域名查剖,請(qǐng)傳入
*/
host?: string;
/**
* url: 請(qǐng)求接口名
*/
url?: string;
/**
* method: RequestMethod 請(qǐng)求方法
*/
methodType?: RequestMethod;
/**
*
* */
header?: Record<string, any>;
/**
* queryParams: 請(qǐng)求參數(shù)
*/
queryParams?: Record<string, any>;
/**
* Additional data of the request.
* extraData: 當(dāng)使用POST請(qǐng)求時(shí)此字段用于傳遞內(nèi)容
*/
extraData?: Record<string, any>;
/**
* encryptionParam: 加密后的參數(shù)
*/
encryptionParam?: Record<string, any>;
/**
* expectDataType
* 指定返回?cái)?shù)據(jù)的類型。如果設(shè)置了此參數(shù)鞭光,系統(tǒng)將優(yōu)先返回指定的類型
*/
expectDataType?: http.HttpDataType = http.HttpDataType.OBJECT;
/**
* usingCache
* 是否使用緩存吏廉,默認(rèn)為true。
* */
usingCache?: boolean = false
/**
* priority
* 優(yōu)先級(jí)惰许,范圍[1,1000]席覆,默認(rèn)是1
* */
priority?: number = 1
/**
* readTimeout
* 讀取超時(shí)時(shí)間。單位為毫秒(ms)汹买,默認(rèn)為60000ms娜睛。
* 設(shè)置為0表示不會(huì)出現(xiàn)超時(shí)情況
* */
readTimeout?: number = 60000
/**
* connectionTimeOut
* 連接超時(shí)時(shí)間。單位為毫秒(ms)卦睹,默認(rèn)為60000ms
* */
connectionTimeOut?: number = 60000
/**
* usingProtocol
* 使用協(xié)議畦戒。默認(rèn)值由系統(tǒng)自動(dòng)指定。
* */
usingProtocol?: http.HttpProtocol = http.HttpProtocol.HTTP1_1
}
2. RequestConfiguration
export class RequestConfiguration {
static configurationRequestOptions(requestOption: RequestOption): Record<string, any> {
return {
url: requestOption.host + requestOption.url,
method: requestOption.methodType, // 可選结序,默認(rèn)為http.RequestMethod.GET
// 開發(fā)者根據(jù)自身業(yè)務(wù)需要添加header字段
header: this.dealHeader(requestOption.header),
// query請(qǐng)求參數(shù)
queryParams: this.dealParam(requestOption.queryParams),
// 當(dāng)使用POST請(qǐng)求時(shí)此字段用于傳遞內(nèi)容
extraData: this.dealExtraData(requestOption.extraData),
encryptionParam: this.encryptionParam(requestOption.extraData),
expectDataType: requestOption.expectDataType, // 可選障斋,指定返回?cái)?shù)據(jù)的類型
usingCache: requestOption.usingCache, // 可選,默認(rèn)為true
priority: requestOption.priority, // 可選徐鹤,默認(rèn)為1
readTimeout: requestOption.readTimeout, // 可選垃环,默認(rèn)為60000ms
connectTimeout: requestOption.connectionTimeOut, // 可選,默認(rèn)為60000ms
usingProtocol: requestOption.usingProtocol, // 可選返敬,協(xié)議類型默認(rèn)值由系統(tǒng)自動(dòng)指定
};
}
static setCookie(): Record<string, any> {
return []
}
static isValidUrl(): Boolean {
return true
}
static dealHeader(header: Record<string, any>): Record<string, any> {
var newHeader = header ?? {}
newHeader["Content-Type"] = "application/json"
return newHeader
}
static dealParam(param: Record<string, any>): Record<string, any> {
var newParam = param ?? {}
return newParam
}
static dealExtraData(extraData: Record<string, any>): Record<string, any> {
var newExtraData = extraData ?? {}
return newExtraData
}
static encryptionParam(extraParam: Record<string, any>): Record<string, any> {
// 對(duì)參數(shù)進(jìn)行加密處理
return {}
}
}
3. 網(wǎng)絡(luò)請(qǐng)求方法枚舉RequestMethod
export enum RequestMethod {
GET = "GET",
POST = "POST",
OPTIONS = "OPTIONS",
HEAD = "HEAD",
PUT = "PUT",
DELETE = "DELETE",
TRACE = "TRANCE",
CONNECT = "CONNECT"
}
4. 請(qǐng)求管理類 HttpManager
export class HttpManager {
/**
* 發(fā)送請(qǐng)求
* @param RequestOptions
* @return Promise
*/
static requestApi<T>(requestOption: RequestOption): Promise<ResponseModel<T>> {
// 網(wǎng)絡(luò)請(qǐng)求中遂庄,可以在此處理requestOption
return RequestImplement.requestApi<T>(requestOption);
}
}
5. 實(shí)際請(qǐng)求類 RequestImplement
export class RequestImplement {
static requestApi<T>(requestOption: RequestOption): Promise<ResponseModel<T>> {
return new Promise<ResponseModel<T>>((resolve, reject) => {
let resolveFunction = resolve;
let rejectFunction = reject;
// 每一個(gè)httpRequest對(duì)應(yīng)一個(gè)HTTP請(qǐng)求任務(wù),不可復(fù)用
let httpRequest = http.createHttp();
// 用于訂閱HTTP響應(yīng)頭劲赠,此接口會(huì)比request請(qǐng)求先返回涛目。可以根據(jù)業(yè)務(wù)需要訂閱此消息
// 從API 8開始凛澎,使用on('headersReceive', Callback)替代on('headerReceive', AsyncCallback)霹肝。 8+
httpRequest.on('headersReceive', (header) => {
console.info('header: ' + JSON.stringify(header));
});
var resModel: ResponseModel<T>
console.log(JSON.stringify(RequestConfiguration.configurationRequestOptions(requestOption)))
let configuration = RequestConfiguration.configurationRequestOptions(requestOption)
httpRequest.request(
// 填寫HTTP請(qǐng)求的URL地址,可以帶參數(shù)也可以不帶參數(shù)塑煎。URL地址需要開發(fā)者自定義沫换。請(qǐng)求的參數(shù)可以在extraData中指定
configuration.url,
configuration,
(err, response) => {
if (!err) {
ResponseHandler.responseHandler<T>(configuration.url, response, (responseModel) => {
resModel = responseModel as ResponseModel<T>
if (responseModel.isSuccess) {
resolveFunction(responseModel)
} else {
rejectFunction(responseModel)
}
})
} else {
console.info('error:' + JSON.stringify(err));
// // 取消訂閱HTTP響應(yīng)頭事件
// httpRequest.off('headersReceive');
// 當(dāng)該請(qǐng)求使用完畢時(shí),調(diào)用destroy方法主動(dòng)銷毀
// httpRequest.destroy();
resModel = new ResponseModel(err.message, err.code, false, "", null);
resolveFunction(resModel)
}
PrettyPrint.printRequestLog(requestOption, resModel)
});
})
}
}
6. 請(qǐng)求結(jié)果處理類 ResponseHandler
export class ResponseHandler {
static responseHandler<T>(url: String, response: http.HttpResponse, reBackResponseModel: (responseModel: ResponseModel<T>) => void ): void {
let responseModel: ResponseModel<T> = new ResponseModel("", 10000, false, "", null);
// 需要處理Url
if (url == "") {
return
}
if (http.ResponseCode.OK == response.responseCode) {
responseModel.data = JSON.stringify(response.result)
console.log(`typeof=====${typeof response.result}`)
let tModel: T = JSON.parse(JSON.stringify(response.result));
if (tModel) {
responseModel.msgCode = 200
responseModel.isSuccess = true
responseModel.resultModel = tModel
} else {
responseModel.msgCode = response.result["code"]
responseModel.msg = response.result["message"]
}
reBackResponseModel(responseModel)
} else {
// 請(qǐng)求失敗
responseModel.msg = 'request fail'
reBackResponseModel(responseModel)
}
}
}
7.請(qǐng)求結(jié)果處理后返回?cái)?shù)據(jù)模型
export class ResponseModel<T> {
msg?: string
msgCode?: number
isSuccess?: Boolean
data?: string | Object | ArrayBuffer
resultModel?: T
constructor(msg: string = "", msgCode: number = 10000, isSuccess: Boolean = false, data: string = "", resultModel: T) {
this.msg = msg
this.msgCode = msgCode
this.isSuccess = isSuccess
this.data = data
this.resultModel = resultModel
}
responseIsSuccess(): Boolean {
return this.isSuccess ?? false
}
}
8. 網(wǎng)絡(luò)請(qǐng)求工具類
/// 日志打印不全處理
static printLongLog(message: string) {
let maxLogSize = 400
for (let i = 0; i < message.length / maxLogSize; i++) {
let start = i * maxLogSize
let end = (i + 1) * maxLogSize
end = end > message.length ? message.length : end
console.log(message.substring(start, end))
}
}
}
9. 請(qǐng)求日志打印類
export class PrettyPrint {
static printRequestLog<T>(requestOption: RequestOption, responseModel: ResponseModel<T>) {
console.log("");
console.log(
"????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????");
console.log("?????????????? ------ 請(qǐng)求開始 ------ ??????????????");
console.log("請(qǐng)求接口名:");
console.log("url = " + requestOption.url);
console.log("請(qǐng)求頭參數(shù):");
console.log("headers = " + JSON.stringify(requestOption.header));
console.log("初始參數(shù):");
console.log("incomeParam = " + JSON.stringify(requestOption.queryParams));
console.log("incomeExtraData = " + JSON.stringify(requestOption.extraData));
console.log("加密請(qǐng)求參數(shù):");
console.log("encryptionParam = " + JSON.stringify(requestOption.encryptionParam));
if (responseModel?.isSuccess) {
console.log("返回結(jié)果:");
console.log("response = ")
RequestTools.printLongLog(responseModel.data.toString())
} else {
console.log("失敗日志:");
console.log("errorInfo = " + responseModel?.msgCode + responseModel?.msg);
}
console.log("?????????????? ------ 請(qǐng)求結(jié)束 ------ ??????????????");
console.log(
"???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????");
}
}
10. 本文以HAR模式實(shí)現(xiàn)
在index.ets中導(dǎo)出兩個(gè)類
export { HttpManager } from './src/main/ets/http/RequestHttpManager'
export { RequestMethod } from './src/main/ets/http/RequestMethod'
三最铁、請(qǐng)求示例
static getHomeAdvertisementData(reBack: (models: Array<CAHomeAdvModel>, error: BaseError) => void) {
// 配置請(qǐng)求參數(shù)
let param: Record<string, string> = { "aa": "1", "bb": "0" }
HttpManager.requestApi<ResultBaseModel<Array<CAHomeAdvModel>>>({
host: "你的host: http://domain",
url: "接口名",
methodType: RequestMethod.POST,
extraData: param
}).then((responseModel) => {
console.log("請(qǐng)求結(jié)果: " + JSON.stringify(responseModel))
}).catch((error: BaseError) => {
console.log("失敗信息:" + JSON.stringify(error))
})