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类实现:

const  TAG = "HttpUtils"
const BASE_URL = "https://www.wanandroid.com"
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
      }

    }

  }

  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: {
   
          extraData = Object.fromEntries(parameter)
          break;
        }
        case RequestMethod.GET: {
   
          const urlParams = Object.keys(parameter).map(key => `${
     key}=${
     parameter[key]}`).join('&')
          if (url.includes("?")) {
   
            url = `${
     url}${
     urlParams}`
          } else {
   
            url = `${
     url}?${
     urlParams}`
          }
          break;
        }
      }
    }

    LogUtils.debug(TAG, "==================Request====================")
    LogUtils.debug(TAG, "url: " + url)
    LogUtils.debug(TAG, "method: " + method.toString())
    if (reqMethod == RequestMethod.POST)
      LogUtils.debug(TAG, "extraData: " + JSON.stringify(parameter, null, 2))
    return new Promise((resolve, reject) => {
   
      httpRequest.request(url,
        {
   
          method,
          readTimeout: HttpUtils.READ_TIME_OUT,
          connectTimeout: HttpUtils.CONNECT_TIME_OUT,
          header: {
   
            'Content-Type': 'application/json'
          },
          extraData
        }
      ).then((value) => {
   
        LogUtils.debug(TAG, "==================Response====================")
        LogUtils.debug(TAG, "url: " + url)
        LogUtils.debug(TAG, "method: " + method.toString())
        LogUtils.debug(TAG, "header: " + JSON.stringify(value.header, null, 2))
        LogUtils.debug(TAG, "responseCode: " + value.responseCode)
        LogUtils.debug(TAG, "resultType: " + value.resultType)
        if (value.responseCode == http.ResponseCode.OK) {
   
          let result: ResponseResult<T> = JSON.parse(value.result.toString())
          LogUtils.debug(TAG, "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})
    })
  }

日志输出:

在这里插入图片描述

参考

  • https://developer.huawei.com/consumer/cn/training/course/slightMooc/C101667364948559963?ha_linker=eyJ0cyI6MTcwMjE3NzI3OTYyMywiaWQiOiI4MmM3ZTI1MmFmMDJlMDZiODBmOGU1ZDM5ZTI5YmMyOCJ9
  • https://www.wanandroid.com/blog/show/2

相关推荐

  1. 鸿蒙应用开发-http网络请求封装

    2023-12-11 10:40:03       10 阅读
  2. 鸿蒙(HarmonyOS)应用开发——http的使用

    2023-12-11 10:40:03       48 阅读
  3. Harmonyos系统使用http访问网络应用数据管理

    2023-12-11 10:40:03       32 阅读

最近更新

  1. TCP协议是安全的吗?

    2023-12-11 10:40:03       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2023-12-11 10:40:03       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2023-12-11 10:40:03       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2023-12-11 10:40:03       20 阅读

热门阅读

  1. SQL命令---删除数据表

    2023-12-11 10:40:03       36 阅读
  2. nginx

    nginx

    2023-12-11 10:40:03      28 阅读
  3. OVS主线流程

    2023-12-11 10:40:03       37 阅读
  4. 4-Docker命令之docker commit

    2023-12-11 10:40:03       28 阅读
  5. shell语言中expect交互

    2023-12-11 10:40:03       36 阅读
  6. 飞天使-rsync大文件断点续传与vim批量删除

    2023-12-11 10:40:03       33 阅读
  7. 文本预处理(text preprocess)总结

    2023-12-11 10:40:03       36 阅读
  8. 命运天注定?

    2023-12-11 10:40:03       34 阅读
  9. 为一个文件夹中的所有文件名前添加前缀

    2023-12-11 10:40:03       30 阅读