HarmonyOS鸿蒙应用开发——HTTP网络访问与封装

网络基础

基本使用

鸿蒙应用发起HTTP请求的基本使用,如下:

  • 导入http模块
  • 创建httpRequest对象
  • 发起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模块的基本封装,在此基础上可以设计一套拦截器来辅助业务需求。

参考

  • https://developer.huawei.com/consumer/cn/training/course/slightMooc/C101667364948559963?ha_linker=eyJ0cyI6MTcwMjE3NzI3OTYyMywiaWQiOiI4MmM3ZTI1MmFmMDJlMDZiODBmOGU1ZDM5ZTI5YmMyOCJ9
  • https://www.wanandroid.com/blog/show/2
  • 23
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
鸿蒙华为公司自主研发的操作系统,而“鸿蒙 JS 网络封装”指的是在鸿蒙操作系统中使用 JavaScript 进行网络封装鸿蒙 JS 网络封装是为了方便开发者使用 JavaScript 语言来进行网络相关的操作,比如发送网络请求、处理网络响应等。通过封装网络功能,开发者可以更加便捷地在鸿蒙操作系统上开发网络相关的应用。 鸿蒙 JS 网络封装提供了一系列 API 和函数,开发者可以使用这些接口进行网络请求。它包括了网络请求的发起、参数的设置、请求头的添加、响应结果的处理等功能。开发者可以根据自己的需求,使用这些函数进行网络操作。 使用鸿蒙 JS 网络封装可以帮助开发者实现以下功能: 1. 发送网络请求:开发者可以使用封装的函数发送 GET 或 POST 请求到指定的服务器地址,并获得服务器返回的结果。 2. 设置请求参数:通过网络封装,开发者可以设置请求的参数,比如请求的地址、请求的数据、请求超时时间等。 3. 处理响应结果:开发者可以通过网络封装获取服务器返回的响应结果,并对结果进行处理,比如解析 JSON 数据、处理错误信息等。 总之,鸿蒙 JS 网络封装提供了一种方便快捷的方式,让开发者可以使用 JavaScript 语言在鸿蒙操作系统上进行网络相关的操作。这对于开发鸿蒙应用的开发者来说,是一个有益的工具,能够提高开发效率,简化网络操作的流程,同时也为用户提供更好的使用体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值