封装网络请求 鸿蒙APP HarmonyOS ArkTS

news/2024/8/26 13:25:04 标签: 网络, harmonyos, 华为

一、效果展示

通过在页面直接调用 userLogin(params) 方法,获取登录令牌

在这里插入图片描述

二、申请网络权限

访问网络时候首先需要申请网络权限,需要修改 src/main 目录下的 module.json5 文件,加入 requestPermissions 属性,详见官方文档
【声明权限】https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/declare-permissions-V5

{
  "module": {
    // ...
    "requestPermissions":[
      {
        "name" : "ohos.permission.INTERNET",
        "usedScene": {
          "abilities": [
            "FormAbility"
          ],
          "when":"inuse"
        }
      },
      {
        "name" : "ohos.permission.GET_NETWORK_INFO",
        "usedScene": {
          "abilities": [
            "FormAbility"
          ],
          "when":"inuse"
        }
      }
    ]
  }
}

三、实现代码

共分为 7 个步骤,其中第 1、2、3、5 步都是创建基础实体,第 4 步为请求工具封装、第 6 步为API封装、第 7 步为页面调用测试,我会在最后贴上文件目录结构

1、创建常量类 CommonConstant.ets

在这个常量类中主要定义后端服务IP端口,以及一些需要使用的状态码信息

/**
 * HTTP API
 */
export class Domain {

  // 后端服务IP
  static readonly SERVER: string = 'http://localhost:8999'

}

/**
 * HTTP状态类
 */
export class HttpStatus {

  // 成功
  static readonly SUCCESS: number = 200

  // 失败
  static readonly ERROR: number = 500

}

export const enum ContentType {

  // 响应体类型
  JSON = 'application/json'
  
}

2、创建请求实体类 RequestBody.ets

这个请求实体类主要可以实现简单的传输【请求地址、请求方式、请求参数】这三个参数,再经过封装的工具去发送网络请求

export class RequestBody {

  url: string;

  method: string;

  data: Object;

  constructor() {
    this.url = ''
    this.method = 'GET'
    this.data = new Object
  }
}

3、创建响应实体类 ResponseResult.ets

这个响应实体主要对应后台的返回参数,比如我这里定义的后台响应码为【code】,信息为【msg】,响应数据为【data】,这个可以自行修改

export class ResponseResult {

  code: number;

  msg: string | Resource;

  data: ArrayBuffer | Object | string

  constructor() {
    this.code = 0;
    this.msg = '';
    this.data = '';
  }
}

4、创建请求工具类 HttpRequest.ets

详见官方文档
【HTTP数据请求】https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/http-> request-V5
【异步并发概述 (Promise和async/await)】https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/async-concurrency-overview-V5#promise

// 这里需要引入第 2 步和第 3 步创建的请求和响应实体
import { ResponseResult } from '../response/ResponseResult'
import { RequestBody } from '../response/RequestBody'

// 这里需要引入第 1 步公共常量类
import { Domain, HttpStatus, ContentType } from '../constant/CommonConstant'

// 这里引用 HTTP 库
import http from '@ohos.net.http'

// HTTP响应处理时候需要的库
import { BusinessError } from '@kit.BasicServicesKit';

class HttpRequest {
  request(requestBody: RequestBody) {
    const promise: Promise<ResponseResult> = new Promise((resolve: Function, reject: Function) => {

      console.log('创建HTTP请求,请求地址:' + Domain.SERVER + requestBody.url + ',请求方式:' + requestBody.method + ',请求体:' + JSON.stringify(requestBody.data))

      // 创建HTTP请求
      const httpRequest = http.createHttp()

	  // 在这里发送 HTTP 请求,并且需要设置Url、Header、Body等信息
      httpRequest.request(
        Domain.SERVER + requestBody.url,
        {
          method: isPost(requestBody.method) ? http.RequestMethod.POST : http.RequestMethod.GET,
          readTimeout: 10000,
          header: {
            'Content-Type': ContentType.JSON
          },
          connectTimeout: 10000,
          extraData: requestBody.data
        },
        (err: BusinessError, data: http.HttpResponse) => {
          // 回调之后判断是否提示 Error
          if (!err) {

            let result = `${data.result}`
            let resultJSON: ResponseResult = JSON.parse(result)

	        // 判断响应码是否成功
            if (data.responseCode === HttpStatus.SUCCESS) {

              if (resultJSON.code === 0) {
                console.info('请求成功:' + resultJSON.data)

                resolve(resultJSON)
              } else {
                reject(new Error('' + resultJSON.msg))
                errorDialog('' + resultJSON.msg)
              }
            } else {
              reject(new Error('' + resultJSON.msg))
              errorDialog('' + resultJSON.msg)
            }

            // 当该请求使用完毕时,调用destroy方法主动销毁
            httpRequest.destroy();
          } else {
            console.error('ERROR:' + JSON.stringify(err));

            if (err.code === 2300007) {
              errorDialog('无法连接至服务器,请稍后重试')
            }

            if (err.code === 2300028) {
              errorDialog('当前网络环境不稳定,请稍后重试')
            }

            // 当该请求使用完毕时,调用destroy方法主动销毁
            httpRequest.destroy();

            reject(new Error('当前网络环境不稳定,请稍后重试'))
          }
        }
      )
    })

    return promise;
  }
}

const httpRequest = new HttpRequest();
export default httpRequest as HttpRequest;

// 判断是否是GET方法
function isGet(method: string): boolean | undefined {

  if (method === http.RequestMethod.GET) {
    return true;
  }

  return false;
}

// 判断是否是POST方法
function isPost(method: string): boolean | undefined {

  if (method === http.RequestMethod.POST) {
    return true;
  }

  return false;
}

// 提示错误
function errorDialog(msg: string) {
  console.error(msg)
}

5、创建一个用户登录实体 userInfo.ets

这个用户实体类包含用户的账号和密码信息,是登录所需

export class UserInfo {

  account: string;

  password: string;

  constructor() {
    this.account = ''
    this.password = ''
  }
}

6、创建一个用户API user.ets

这个API的作用就是统一格式,统一使用【url】、【data】、【method】这三个进行网络请求,也是在请求工具类 HttpRequest.ets 基础上的二次封装

// 这里引入第 4 步创建的请求工具类
import HttpRequest from '../request/HttpRequest'

// 这里引入第 3 步创建的响应体
import { ResponseResult } from '../response/ResponseResult'

// 这里引入第 5 步创建的自定义用户对象,主要用于定义各参数的类型
import { UserInfo } from '../../entity/userInfo'

// 用户登录 API
export function userLogin(params: UserInfo): Promise<ResponseResult> {
  return HttpRequest.request({
    url: '/auth/login',
    data: params,
    method:'POST'
  })
}

7、在页面尝试调用 index.ets

最后在我们的页面启动时直接调用 user.ets 中的 userLogin 方法进行登录测试

// 这里需要引入第 6 步创建的用户API
import { userLogin } from '../common/api/user';

@Entry
@Component
struct Index {

  // 在进入页面时调用 userLogin 接口进行测试
  aboutToAppear(): void {
    userLogin({account: 'admin', password: 'Admin@2024'}).then(res => {
      console.info('页面成功获取到用户信息:' + res.data)
    })
  }

  build() {
    RelativeContainer() {
      
    }
  }
}

四、目录结构

总共 7 个步骤创建了 7 个文件,希望对您有所帮助

在这里插入图片描述


http://www.niftyadmin.cn/n/5558255.html

相关文章

Dify v0.6.14源码部署

一.前置条件 1.安装和配置poetry 通过Windows PowerShell安装poetry&#xff1a; (Invoke-WebRequest -Uri https://install.python-poetry.org -UseBasicParsing).Content | python -关于poetry相关配置参考文献[1]。 2.下载dify和启动中间件容器 克隆Dify v0.6.14代码&am…

<数据集>钢铁缺陷检测数据集<目标检测>

数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;6572张 标注数量(xml文件个数)&#xff1a;6572 标注数量(txt文件个数)&#xff1a;6572 标注类别数&#xff1a;4 标注类别名称&#xff1a;[class-1, class-3, class-4, class-2] 序号类别名称图片数框数1class…

自动化创建 AWS RDS 实例告警

在管理 AWS RDS 数据库实例时,设置适当的监控和告警是至关重要的。本文将介绍如何使用 Python 和 AWS SDK (boto3) 自动化创建 RDS 实例的 CloudWatch 告警。 背景 对于大规模的 RDS 部署,手动为每个实例创建告警既耗时又容易出错。通过自动化这个过程,我们可以确保所有符…

linux的学习(七):读取,函数,正则表达式,文本处理工具cut和awk

##简介 shell编程中的读取&#xff0c;函数&#xff0c;正则表达式&#xff0c;文本处理工具的简单使用 read read&#xff1a;读取控制台的输入 参数&#xff1a; -p&#xff1a;指定读取时的提示符-t&#xff1a;等待读取的时间 脚本例子 编写i.sh脚本&#xff0c;enter…

java包装类 及其缓存

Java 包装类&#xff08;Wrapper Class&#xff09;是将基本数据类型转换为对象的方式&#xff0c;每个基本数据类型在 java.lang 包中都有一个相应的包装类&#xff1a; Boolean 对应基本类型 boolean Character 对应基本类型 char Integer 对应基本类型 int Float 对应基本…

【HarmonyOS学习】定位相关知识(Locationkit)

简介 LocationKit提供了定位服务、地理围栏、地理编码、逆地理编码和国家码等功能。 可以实现点击获取用户位置信息、持续获取位置信息和区域进出监控等多项功能。 需要注意&#xff0c;需要确定用户已经开启定位信息&#xff0c;一下的代码没有做这一步的操作&#xff0c;默…

Laravel与Redis的共舞:释放高性能缓存的潜力

Laravel与Redis的共舞&#xff1a;释放高性能缓存的潜力 在现代Web应用开发中&#xff0c;性能优化始终是关键议题&#xff0c;而缓存则是提升性能的重要手段之一。Laravel框架集成了对Redis这一高性能键值存储系统的支持&#xff0c;使得数据缓存、会话管理和队列处理变得简单…

安装adb和常用命令

下载ADB安装包 https://dl.google.com/android/repository/platform-tools-latest-windows.zip 解压安装包 解压如上下载的安装包&#xff0c;然后复制adb.exe所在的文件地址 配置环境变量 我的电脑——>右键属性——>高级系统设置——>环境变量——>系统变量—…