封装网络请求 鸿蒙APP HarmonyOS ArkTS

一、效果展示

通过在页面直接调用 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 个文件,希望对您有所帮助

相关推荐
赖small强4 分钟前
【Linux 网络基础】Linux 平台 DHCP 运作原理与握手过程详解
linux·网络·dhcp
Mu.38729 分钟前
计算机网络模型
网络·网络协议·计算机网络·安全·http·https
xixixi777773 小时前
解析一下传输安全——“它是什么”,更是关于“它为何存在”、“如何实现”以及“面临何种挑战与未来”
网络·安全·通信
威哥爱编程3 小时前
鸿蒙6开发中,UI相关应用崩溃常见问题与解决方案
harmonyos·arkts·arkui
威哥爱编程3 小时前
鸿蒙6开发视频播放器的屏幕方向适配问题
harmonyos·arkts·arkui
威哥爱编程3 小时前
HarmonyOS 6.0 蓝牙实现服务端和客户端通讯案例详解
harmonyos
威哥爱编程3 小时前
鸿蒙6开发中,通过文本和字节数组生成码图案例
harmonyos·arkts·arkui
kirk_wang4 小时前
HarmonyOS碰一碰赋能电商场景:订单信息无缝分享的落地实践
华为·harmonyos
n***i954 小时前
HarmonyOS在智能穿戴中的可穿戴设备
华为·harmonyos
jerryinwuhan4 小时前
socket由浅入深
网络