封装网络请求 鸿蒙APP HarmonyOS ArkTS

news2024/9/24 21:28:37

一、效果展示

通过在页面直接调用 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.coloradmin.cn/o/1931989.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Flink底层原理解析:案例解析(第37天)

系列文章目录 一、flink架构 二、Flink底层原理解析 三、Flink应用场景解析 四、fink入门案例解析 文章目录 系列文章目录前言一、flink架构1. 作业管理器&#xff08;JobManager&#xff09;2. 资源管理器&#xff08;ResourceManager&#xff09;3. 任务管理器&#xff08;Ta…

Hadoop安装报错

报错&#xff1a;ERROR 2023-03-09 21:33:00,178 NetUtil.py:97 - SSLError: Failed to connect. Please check openssl library versions. 解决方案: 在安装失败得客户端执行 编辑 /etc/python/cert-verification.cfg 配置文件&#xff0c;将 [https] 节的 verify 项 设为禁用…

【教学类-67-02】20240716毛毛虫ABB排序

背景需求&#xff1a; 【教学类-67-01】20240715毛毛虫AB排序-CSDN博客文章浏览阅读584次&#xff0c;点赞16次&#xff0c;收藏6次。【教学类-67-01】20240715毛毛虫AB排序https://blog.csdn.net/reasonsummer/article/details/140443310 在AB排序基础上&#xff0c;继续制作…

【JavaEE精炼宝库】 初识网络原理——网络通信基础 | 协议

文章目录 一、网络发展史1.1 独立模式&#xff1a;1.2 网络互连&#xff1a;1.3 局域网&#xff08;LAN&#xff09;&#xff1a;1.4 广域网&#xff08;WAN&#xff09;&#xff1a; 二、网络通信基础2.1 IP地址&#xff1a;2.2 端口号&#xff1a; 三、协议3.1 协议的概念&am…

RabbitMQ:基础篇

1.RabbitMQ是高性能的异步通讯组件 何为异步通讯 打电话就是同步通讯&#xff0c;微信聊天可以理解为异步通讯&#xff0c;不是实时的进行通讯&#xff1a;时效性差。 同步调用的缺点&#xff1a; 拓展性差&#xff08;需求不尽提&#xff09; 性能下降 级联失败 …

实时高清无延迟:EasyDSS/EasyCVR无人机直播技术重塑赛事新体验

近日有网友发视频称&#xff0c;在内蒙古呼伦贝尔一景区的马术表演现场&#xff0c;一架无人机擅自在场地上空飞行拍摄。现场工作人员多次制止飞行无果&#xff0c;一名表演者骑马用弓箭将无人机射落。 在数字科技日新月异的今天&#xff0c;无人机直播推流技术以其独特的视角…

在GPU上运行PyTorch

文章目录 1、查看GPU的CUDA版本2、下载CUDA版本3、安装cuDNN4、配置CUDA环境变量5、安装配置Anaconda6、使用Anaconda7、pycharm导入虚拟环境8、安装带GPU的PyTorch⭐9、总结 &#x1f343;作者介绍&#xff1a;双非本科大三网络工程专业在读&#xff0c;阿里云专家博主&#x…

字节跳动十年经验老鸟,耗时大半年整理的软件测试面试真题【附答案】

软件测试工程师&#xff0c;和开发工程师相比起来&#xff0c;虽然前期可能不会太深&#xff0c;但是涉及的面还是比较广的。前期面试实习生或者一年左右的岗位&#xff0c;问的也主要是一些基础性的问题比较多。涉及的知识主要有MySQL数据库的使用、Linux操作系统的使用、软件…

回溯算法的去重问题

概述 在利用回溯算法去求子集、排列、组合等问题时&#xff0c;所给数组中如果包含重复元素&#xff0c;需要进行去重操作。常用的去重方法是使用used数组或集合。 对于上述子集、排列、组合等问题的求解方法是将数组转化为树的形式&#xff0c;利用递归和回溯的方法进行求解…

10.1 JSP语言入门

JSP语言入门 目录一、 基础概念1. 什么是JSP&#xff1f;2. 工作原理3. 基本语法 二、 表达式语言&#xff08;EL&#xff09;1. 简介2. 语法 三、 JSTL&#xff08;JSP Standard Tag Library&#xff09;1. 简介2. 核心标签库3. 常用标签 四、 高级话题1. 会话管理2. 自定义标…

卷积神经网络(一)-LeNet-5

前言 LeNet开启了卷积神经网络的第一枪&#xff0c;这一网络模型由Yann LeCun等人在1998年提出&#xff0c;被视为卷积神经网络的开山之作。 论文地址&#xff1a; http://yann.lecun.com/exdb/publis/pdf/lecun-01a.pdf 如果打不开就看csdn&#xff1a; https://download.…

LangChain-v0.2 Build an Agent 构建代理

语言模型本身不能采取行动&#xff0c;它们只是输出文本。LangChain的一个重要用例是创建代理。代理是使用LLM作为推理引擎来确定要采取哪些行动&#xff0c;以及传递哪些输入的系统。执行操作后&#xff0c;可以将结果反馈到LLM中&#xff0c;以确定是否需要更多操作&#xff…

陪玩系统小程序模式APP小程序H5系统搭建开发

随着移动互联网的营及和游戏行业的蓬轨发展&#xff0c;陪玩服务应远而生并迅速唱起&#xff0c;陪玩系统小程序作为连接游戏玩家与陪玩师的桥梁&#xff0c;其模式系统的搭建与开发是得尤为重要&#xff0c;本文将洋细凰述陪玩系统小程宗模式系统的搭建开发流程&#xff0c;包…

基础动态规划题目基础动态规划题目

目录 题目1&#xff1a; P1216 [USACO1.5] [IOI1994]数字三角形 Number Triangles 代码示例&#xff1a; 题目2&#xff1a; Common Subsequence 代码示例 题目3 &#xff1a;最长上升子序列 最长不下降子序列 最长上升子序列oj答案 题目1&#xff1a; P1216 [USACO1.5]…

Linux热键,shell含义及权限介绍

君子忧道不忧贫。 —— 孔丘 Linux操作系统的权限 1、几个常用的热键介绍1、1、[Tab]键1、2、[ctrl]-c1、3、[ctrl]-d1、4、[ctrl]-r 2、shell命令以及运行原理3、权限3、1、什么是权限3、2、权限的本质3、3、Linux中的用户3、4、Linux中文件的权限3、4、1、快速掌握修改权限的…

华为HCIP Datacom H12-821 卷41

1.多选题 以下关于BGP Atomic_Aggregate和Aggregator的描述&#xff0c;正确的是哪些项? A、Aggregator属性属于可选过渡属性 B、Atomic_Aggregate属于公认任意属性 C、收到携带Atomic_Aggregate属性的路由表示这条路由不能再度明细化 D、 Agregator表示某条路由可能出现…

古玻璃制品的成分分析与鉴别详解【国一,附完整代码】

声明&#xff1a;2024年数模国赛即将来临&#xff0c;为助力国赛和钉钉杯&#xff0c;我将重温22年小样本国赛C题和23年大样本国赛C题&#xff0c;给出详细思路和完整代码&#xff0c;供广大数模爱好者阅览&#xff0c;如需比赛指导&#xff0c;请联系文章底部卡片咨询。 未经允…

UNiapp微信小程序Ucharts

效果图如下 以上为加载接口所得数据的玫瑰图与折线图 具体步骤如下 1&#xff0c;将插件导入Hbuiler 所需要的项目中&#xff08;插件地址&#xff1a;秋云 ucharts echarts 高性能跨全端图表组件 - DCloud 插件市场&#xff09; 2&#xff0c;导入成功是这样的 3&#xff0c…

Windows终端远程登陆Linux服务器(SSH+VScode)

W i n d o w s 终端远程登陆 L i n u x 服务器&#xff08; S S H V S c o d e &#xff09; \huge{Windows终端远程登陆Linux服务器&#xff08;SSHVScode&#xff09;} Windows终端远程登陆Linux服务器&#xff08;SSHVScode&#xff09; 文章目录 写在前面通过SSH远程连接L…

rust + python+ libtorch

1: 环境&#xff0c;ubuntu 1.1 rust : rust-1.79.0 &#xff08;在官方下载linux版本后&#xff0c;解压文件夹&#xff0c;内部有个install的sh文件&#xff0c;可安装&#xff09; 安装成功测试&#xff1a;cargo --version 1.2 python3.10 (直接使用apt install pytho…