import { ArrayList, HashMap } from '@kit.ArkTS'; import http from '@ohos.net.http'; type HttpParamsGet = { url: string query?: Record | Object headers?: Record } type HttpParamsPost = { url: string data?: Object query?: Record | Object headers?: Record } type HttpParamsForm = { url: string data?: Record | Object query?: Record | Object headers?: Record } export class HttpHelper { private static instance: HttpHelper | null = null // 单例模式 static get() { // 判断系统是否已经有单例了 if (HttpHelper.instance === null) { HttpHelper.instance = new HttpHelper() } return HttpHelper.instance } //请求中队列 private httpHandlerList = new HashMap(); // 并发白名单,这个名单里面的api,重复请求不会取消 private concurrentList = new ArrayList(); constructor() { this.httpHandlerList = new HashMap(); this.concurrentList.clear() } /** * 添加并发白名单 * @param apiNo */ public addConcurrent(apiNo: string) { if (this.concurrentList.getIndexOf(apiNo) === -1) { this.concurrentList.add(apiNo) } } public removeConcurrent(apiNo: string) { if (this.concurrentList.getIndexOf(apiNo) !== -1) { this.concurrentList.remove(apiNo) } } /** * postJson请求 * @param url url地址 * @param headers * @param apiNo 请求标识,取消请求或者去重使用|考虑做自动重试使用 * @returns */ public postJson(params: HttpParamsPost, apiNo?: string): Promise { return new Promise((resolve, reject) => { if (this.concurrentList.getIndexOf(apiNo ?? params.url) === -1 && this.httpHandlerList.hasKey(apiNo ?? params.url)) { this.httpHandlerList.get(apiNo ?? params.url).destroy() this.httpHandlerList.remove(apiNo ?? params.url) } let httpRequest = http.createHttp(); if (this.concurrentList.getIndexOf(apiNo ?? params.url) === -1) { this.httpHandlerList.set(apiNo ?? params.url, httpRequest) } const header = { "Content-Type": "application/json;charset=UTF-8", // "Accept": "application/json", ...params.headers } console.log('=====>', 'POST:', JSON.stringify(params)) // console.log('=====>', '接口请求', JSON.stringify(header)) // console.log('=====>', '接口请求', data) httpRequest.request(this.getUrl(params.url, params.query), { method: http.RequestMethod.POST, connectTimeout: 20000, readTimeout: 20000, header: header, extraData: params.data }) .then((data: http.HttpResponse) => { console.info('=====>' + 'Result:' + data.result as string); // console.info('=====>' + 'code:' + data.responseCode); // console.info('=====>' + 'type:' + JSON.stringify(data.resultType)); // console.info('=====>' + 'header:' + JSON.stringify(data.header)); // console.info('=====>' + 'cookies:' + data.cookies); // 自API version 8开始支持cookie // console.info('=====>' + 'header.content-Type:' + JSON.stringify(data.header)); // console.info('=====>' + 'header.Status-Line:' + JSON.stringify(data.header)); if (this.httpHandlerList.hasKey(apiNo ?? params.url)) { this.httpHandlerList.remove(apiNo ?? params.url) } if (data.responseCode === 200) { resolve((typeof data.result === 'string' ? JSON.parse(data.result) : data.result) as T) } else { reject('服务异常') } }).catch((err: Error) => { if (this.httpHandlerList.hasKey(apiNo ?? params.url)) { this.httpHandlerList.remove(apiNo ?? params.url) } if (err.message === 'Failed writing received data to disk/application') { reject('cancel') } else reject(err) }); }); } /** * postForm请求 * @param url url地址 * @param headers * @param apiNo 请求标识,取消请求或者去重使用|考虑做自动重试使用 * @returns */ public postForm(params: HttpParamsForm, apiNo?: string): Promise { return new Promise((resolve, reject) => { if (this.concurrentList.getIndexOf(apiNo ?? params.url) === -1 && this.httpHandlerList.hasKey(apiNo ?? params.url)) { this.httpHandlerList.get(apiNo ?? params.url).destroy() this.httpHandlerList.remove(apiNo ?? params.url) } let httpRequest = http.createHttp(); if (this.concurrentList.getIndexOf(apiNo ?? params.url) === -1) { this.httpHandlerList.set(apiNo ?? params.url, httpRequest) } const header = { "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8", // "Accept": "application/json", ...params.headers } let data = this.getContent(params.data) console.log('=====>', 'POSTForm:', params.url) console.log('=====>', 'POSTForm:', JSON.stringify(header)) console.log('=====>', 'POSTForm:', data) httpRequest.request(this.getUrl(params.url, params.query), { method: http.RequestMethod.POST, connectTimeout: 20000, readTimeout: 20000, header: header, extraData: data }) .then((data: http.HttpResponse) => { console.info('=====>' + 'Result:' + data.result as string); // console.info('=====>' + 'code:' + data.responseCode); // console.info('=====>' + 'type:' + JSON.stringify(data.resultType)); // console.info('=====>' + 'header:' + JSON.stringify(data.header)); // console.info('=====>' + 'cookies:' + data.cookies); // 自API version 8开始支持cookie // console.info('=====>' + 'header.content-Type:' + JSON.stringify(data.header)); // console.info('=====>' + 'header.Status-Line:' + JSON.stringify(data.header)); if (this.httpHandlerList.hasKey(apiNo ?? params.url)) { this.httpHandlerList.remove(apiNo ?? params.url) } if (data.responseCode === 200) { resolve((typeof data.result === 'string' ? JSON.parse(data.result) : data.result) as T) } else { reject('服务异常') } }).catch((err: Error) => { if (this.httpHandlerList.hasKey(apiNo ?? params.url)) { this.httpHandlerList.remove(apiNo ?? params.url) } if (err.message === 'Failed writing received data to disk/application') { reject('cancel') } else reject(err) }); }); } /** * get请求 * @param url url地址 * @param data 请求参数 * @param headers * @param apiNo 请求标识,取消请求或者去重使用|考虑做自动重试使用 * @returns */ public get(params: HttpParamsGet, apiNo?: string): Promise { return new Promise((resolve, reject) => { if (this.concurrentList.getIndexOf(apiNo ?? params.url) === -1 && this.httpHandlerList.hasKey(apiNo ?? params.url)) { this.httpHandlerList.get(apiNo ?? params.url).destroy() this.httpHandlerList.remove(apiNo ?? params.url) } let httpRequest = http.createHttp(); if (this.concurrentList.getIndexOf(apiNo ?? params.url) === -1) { this.httpHandlerList.set(apiNo ?? params.url, httpRequest) } const header = { ...params.headers } console.log('=====>', 'GET:', this.getUrl(params.url, params.query)) httpRequest.request(this.getUrl(params.url, params.query), { method: http.RequestMethod.GET, connectTimeout: 20000, readTimeout: 20000, header: header, // extraData: params.data }) .then((data: http.HttpResponse) => { // console.info('=====>' + 'Result:' + data.result as string); // console.info('=====>' + 'code:' + data.responseCode); // console.info('=====>' + 'type:' + JSON.stringify(data.resultType)); // console.info('=====>' + 'header:' + JSON.stringify(data.header)); // console.info('=====>' + 'cookies:' + data.cookies); // 自API version 8开始支持cookie // console.info('=====>' + 'header.content-Type:' + JSON.stringify(data.header)); // console.info('=====>' + 'header.Status-Line:' + JSON.stringify(data.header)); if (this.httpHandlerList.hasKey(apiNo ?? params.url)) { this.httpHandlerList.remove(apiNo ?? params.url) } if (data.responseCode === 200) { resolve((typeof data.result === 'string' ? JSON.parse(data.result) : data.result) as T) } else { reject('服务异常') } }).catch((err: Error) => { if (this.httpHandlerList.hasKey(apiNo ?? params.url)) { this.httpHandlerList.remove(apiNo ?? params.url) } if (err.message === 'Failed writing received data to disk/application') { reject('cancel') } else reject(err) }); }); } private getUrl(url: string, query?: Record | Object) { let u = url if (query) { let q = query if (typeof query === 'object') { q = this.classToRecord(query) } u = `${u}${u.indexOf('?') < 0 ? '?' : u.endsWith('$') ? '' : '&'}` Object.entries(q).forEach((row) => { if (row[1]) { u = `${u}${row[0]}=${row[1] as string}&` } }); u = u.slice(0, u.length - 1) } return u } private getContent(data: Record | Object) { let u = '' let q = data if (typeof data === 'object') { q = this.classToRecord(data) } Object.entries(q).forEach((row) => { if (row[1]) { u = `${u}${row[0]}=${row[1] as string}&` } }); u = u.slice(0, u.length - 1) return u } private classToRecord(obj: Object): Record { const record: Record = {} as Record; for (const key in obj) { if (obj.hasOwnProperty(key)) { record[key] = obj[key]; } } return record; } }