赞
踩
鸿蒙应用发起HTTP请求的基本使用,如下:
第一、导入http模块:
import http from '@ohos.net.http'
第二、创建httpRequest对象,注意的是每一个httpRequest对象对应一个http请求任务,不可复用。
const httpRequest = http.createHttp()
第三、发起请求,比如POST
请求
httpRequest.request( // 请求url地址 url, { // 请求方式 method: http.RequestMethod.POST, // 请求的额外数据。 extraData: { "param1": "value1", "param2": "value2", }, // 可选,默认为60s connectTimeout: 60000, // 可选,默认为60s readTimeout: 60000, // 开发者根据自身业务需要添加header字段 header: { 'Content-Type': 'application/json' } }) .then((data) => { if (data.responseCode === http.ResponseCode.OK) { // 处理响应结果 // data.result为服务器返回的业务数据 console.info('Result:' + data.result); console.info('code:' + data.responseCode); } }).catch((err) => { console.info('error:' + JSON.stringify(err)); });
最后需要声明网络权限,在module.josn5文件中声明:
{
"module" : {
"requestPermissions":[
{
"name": "ohos.permission.INTERNET"
}
]
}
}
上面就是网络请求的简单使用,接下来通过Promise
来封装一个网络请求库,统一管理请求参数、响应数据、日志的输出等,对外屏蔽了细节,使用者只需定义业务数据的实体类以及调用即可。
以**玩Android**开放接口为测试用例
定义业务数据的实体类,通过泛型来接收不同的数据类型:
export class ResponseResult<T> {
errorCode: number;
errorMsg: string;
data?: T | Object | string;
}
把各种请求方式用枚举声明RequestMethod
export enum RequestMethod {
OPTIONS,
GET,
HEAD,
POST ,
PUT,
DELETE,
TRACE,
CONNECT
}
其实在http模块中已经有对应的枚举,之所以再用一个新枚举来声明,是简化使用,同时也是将http模块相关细节屏蔽掉不对外开放,这样就可以灵活替换网络库,也具有扩展性。
定义一个HttpUtils
类实现:
export class HttpUtils{ public static readonly SUCCESS_CODE: number = 0 public static readonly READ_TIME_OUT = 60 * 1000 public static readonly CONNECT_TIME_OUT = 60 * 1000 private baseUrl: string = "" constructor(baseUrl: string) { this.baseUrl = baseUrl } private methodName(method: RequestMethod): http.RequestMethod { switch (method){ case RequestMethod.OPTIONS:{ return http.RequestMethod.OPTIONS } case RequestMethod.GET:{ return http.RequestMethod.GET } case RequestMethod.HEAD:{ return http.RequestMethod.HEAD } case RequestMethod.POST:{ return http.RequestMethod.POST } case RequestMethod.PUT:{ return http.RequestMethod.PUT } case RequestMethod.DELETE:{ return http.RequestMethod.DELETE } case RequestMethod.TRACE:{ return http.RequestMethod.TRACE } case RequestMethod.CONNECT:{ return http.RequestMethod.CONNECT } } } private tag(n: string): string { return `${TAG}/${n}` } request<T>(path: string, reqMethod: RequestMethod, parameter: Map<string, Object> = null): Promise<T | null> { // 注意的是每一个httpRequest对象对应一个http请求任务,不可复用。 const httpRequest = http.createHttp() const method = this.methodName(reqMethod) let extraData = {} let url = `${this.baseUrl}/${path}` if (parameter != null) { switch (reqMethod) { case RequestMethod.POST, RequestMethod.PUT: { extraData = Object.fromEntries(parameter) break; } case RequestMethod.GET,RequestMethod.DELETE: { const urlParams = Object.keys(parameter).map(key => `${key}=${parameter[key]}`).join('&') if (url.includes("?")) { url = `${url}${urlParams}` } else { url = `${url}?${urlParams}` } break; } } } let n = Math.random().toString(10).slice(2) LogUtils.debug(this.tag(n), "==================Request====================") LogUtils.debug(this.tag(n), "url: " + url) LogUtils.debug(this.tag(n), "method: " + method.toString()) if (reqMethod == RequestMethod.POST || reqMethod == RequestMethod.PUT) LogUtils.debug(this.tag(n), "extraData: " + JSON.stringify(parameter, null, 2)) return new Promise( async (resolve, reject) => { let beginTime = await systemDateTime.getCurrentTime(false) httpRequest.request(url, { method, readTimeout: HttpUtils.READ_TIME_OUT, connectTimeout: HttpUtils.CONNECT_TIME_OUT, header: { 'Content-Type': 'application/json' }, extraData } ).then( async (value) => { let endTime = await systemDateTime.getCurrentTime(false) LogUtils.debug(this.tag(n), "==================Response====================") LogUtils.debug(this.tag(n), "url: " + url + " "+ (endTime - beginTime)+"ms") LogUtils.debug(this.tag(n), "method: " + method.toString()) LogUtils.debug(this.tag(n), "header: " + JSON.stringify(value.header, null, 2)) LogUtils.debug(this.tag(n), "responseCode: " + value.responseCode) LogUtils.debug(this.tag(n), "resultType: " + value.resultType) if (value.responseCode == http.ResponseCode.OK) { let result: ResponseResult<T> = JSON.parse(value.result.toString()) LogUtils.debug(this.tag(n), "body: " + JSON.stringify(result, null, 2)) if (result.errorCode == HttpUtils.SUCCESS_CODE) { resolve(result.data as T) } else { reject(result.errorMsg) } } else { reject("请求失败") } }).catch((reason) => { reject(reason) }) }) } get<T>(path: string, parameter: Map<string, Object> = null): Promise<T | null> { return this.request<T>(path, RequestMethod.GET, parameter) } post<T>(path: string, parameter: Map<string, Object> = null): Promise<T | null> { return this.request<T>(path, RequestMethod.POST, parameter) } delete<T>(path: string, parameter: Map<string, Object> = null): Promise<T | null> { return this.request<T>(path, RequestMethod.DELETE, parameter) } put<T>(path: string, parameter: Map<string, Object> = null): Promise<T | null> { return this.request<T>(path, RequestMethod.PUT, parameter) } } const YiNet = new HttpUtils(BASE_URL) export default YiNet
使用发起网络请求:
aboutToAppear() { let map = new Map<string,string>() map["cid"] = 294 YiNet.get<ArticleList>("project/list/1/json",map).then((data)=>{ this.data = JSON.stringify(data, null, 2) }) let map2 = new Map<string,string>() map2["username"] = "123" map2["password"] = "123456" YiNet.post<User>("user/login",map2).then((data)=>{ this.data = JSON.stringify(data, null, 2) }).catch((err)=>{ Prompt.showToast({message:err}) }) }
日志输出效果:
如果有多个请求,日志可能会混合交叉不利于查看,可以通过HttpUtils/xxxxxx
来查看具体某一个请求日志,其中xxxx
是一个随机数大部分情况下是具有唯一性。
上面就是官方的http模块的基本封装,在此基础上可以设计一套拦截器来辅助业务需求。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。