封装网络请求 鸿蒙APP HarmonyOS ArkTS

打印 上一主题 下一主题

主题 971|帖子 971|积分 2913

一、结果展示

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

二、申请网络权限

   访问网络时候首先需要申请网络权限,需要修改 src/main 目次下的 module.json5 文件,加入 requestPermissions 属性,详见官方文档
【声明权限】https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/declare-permissions-V5
  1. {
  2.   "module": {
  3.     // ...
  4.     "requestPermissions":[
  5.       {
  6.         "name" : "ohos.permission.INTERNET",
  7.         "usedScene": {
  8.           "abilities": [
  9.             "FormAbility"
  10.           ],
  11.           "when":"inuse"
  12.         }
  13.       },
  14.       {
  15.         "name" : "ohos.permission.GET_NETWORK_INFO",
  16.         "usedScene": {
  17.           "abilities": [
  18.             "FormAbility"
  19.           ],
  20.           "when":"inuse"
  21.         }
  22.       }
  23.     ]
  24.   }
  25. }
复制代码
三、实现代码

   共分为 7 个步骤,其中第 1、2、3、5 步都是创建底子实体,第 4 步为请求工具封装、第 6 步为API封装、第 7 步为页面调用测试,我会在末了贴上文件目次布局
  1、创建常量类 CommonConstant.ets

   在这个常量类中主要定义后端服务IP端口,以及一些需要使用的状态码信息
  1. /**
  2. * HTTP API
  3. */
  4. export class Domain {
  5.   // 后端服务IP
  6.   static readonly SERVER: string = 'http://localhost:8999'
  7. }
  8. /**
  9. * HTTP状态类
  10. */
  11. export class HttpStatus {
  12.   // 成功
  13.   static readonly SUCCESS: number = 200
  14.   // 失败
  15.   static readonly ERROR: number = 500
  16. }
  17. export const enum ContentType {
  18.   // 响应体类型
  19.   JSON = 'application/json'
  20.   
  21. }
复制代码
2、创建请求实体类 RequestBody.ets

   这个请求实体类主要可以实现简朴的传输【请求地址、请求方式、请求参数】这三个参数,再经过封装的工具去发送网络请求
  1. export class RequestBody {
  2.   url: string;
  3.   method: string;
  4.   data: Object;
  5.   constructor() {
  6.     this.url = ''
  7.     this.method = 'GET'
  8.     this.data = new Object
  9.   }
  10. }
复制代码
3、创建响应实体类 ResponseResult.ets

   这个响应实体主要对应后台的返回参数,比如我这里定义的后台响应码为【code】,信息为【msg】,响应数据为【data】,这个可以自行修改
  1. export class ResponseResult {
  2.   code: number;
  3.   msg: string | Resource;
  4.   data: ArrayBuffer | Object | string
  5.   constructor() {
  6.     this.code = 0;
  7.     this.msg = '';
  8.     this.data = '';
  9.   }
  10. }
复制代码
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
  1. // 这里需要引入第 2 步和第 3 步创建的请求和响应实体
  2. import { ResponseResult } from '../response/ResponseResult'
  3. import { RequestBody } from '../response/RequestBody'
  4. // 这里需要引入第 1 步公共常量类
  5. import { Domain, HttpStatus, ContentType } from '../constant/CommonConstant'
  6. // 这里引用 HTTP 库
  7. import http from '@ohos.net.http'
  8. // HTTP响应处理时候需要的库
  9. import { BusinessError } from '@kit.BasicServicesKit';
  10. class HttpRequest {
  11.   request(requestBody: RequestBody) {
  12.     const promise: Promise<ResponseResult> = new Promise((resolve: Function, reject: Function) => {
  13.       console.log('创建HTTP请求,请求地址:' + Domain.SERVER + requestBody.url + ',请求方式:' + requestBody.method + ',请求体:' + JSON.stringify(requestBody.data))
  14.       // 创建HTTP请求
  15.       const httpRequest = http.createHttp()
  16.           // 在这里发送 HTTP 请求,并且需要设置Url、Header、Body等信息
  17.       httpRequest.request(
  18.         Domain.SERVER + requestBody.url,
  19.         {
  20.           method: isPost(requestBody.method) ? http.RequestMethod.POST : http.RequestMethod.GET,
  21.           readTimeout: 10000,
  22.           header: {
  23.             'Content-Type': ContentType.JSON
  24.           },
  25.           connectTimeout: 10000,
  26.           extraData: requestBody.data
  27.         },
  28.         (err: BusinessError, data: http.HttpResponse) => {
  29.           // 回调之后判断是否提示 Error
  30.           if (!err) {
  31.             let result = `${data.result}`
  32.             let resultJSON: ResponseResult = JSON.parse(result)
  33.                 // 判断响应码是否成功
  34.             if (data.responseCode === HttpStatus.SUCCESS) {
  35.               if (resultJSON.code === 0) {
  36.                 console.info('请求成功:' + resultJSON.data)
  37.                 resolve(resultJSON)
  38.               } else {
  39.                 reject(new Error('' + resultJSON.msg))
  40.                 errorDialog('' + resultJSON.msg)
  41.               }
  42.             } else {
  43.               reject(new Error('' + resultJSON.msg))
  44.               errorDialog('' + resultJSON.msg)
  45.             }
  46.             // 当该请求使用完毕时,调用destroy方法主动销毁
  47.             httpRequest.destroy();
  48.           } else {
  49.             console.error('ERROR:' + JSON.stringify(err));
  50.             if (err.code === 2300007) {
  51.               errorDialog('无法连接至服务器,请稍后重试')
  52.             }
  53.             if (err.code === 2300028) {
  54.               errorDialog('当前网络环境不稳定,请稍后重试')
  55.             }
  56.             // 当该请求使用完毕时,调用destroy方法主动销毁
  57.             httpRequest.destroy();
  58.             reject(new Error('当前网络环境不稳定,请稍后重试'))
  59.           }
  60.         }
  61.       )
  62.     })
  63.     return promise;
  64.   }
  65. }
  66. const httpRequest = new HttpRequest();
  67. export default httpRequest as HttpRequest;
  68. // 判断是否是GET方法
  69. function isGet(method: string): boolean | undefined {
  70.   if (method === http.RequestMethod.GET) {
  71.     return true;
  72.   }
  73.   return false;
  74. }
  75. // 判断是否是POST方法
  76. function isPost(method: string): boolean | undefined {
  77.   if (method === http.RequestMethod.POST) {
  78.     return true;
  79.   }
  80.   return false;
  81. }
  82. // 提示错误
  83. function errorDialog(msg: string) {
  84.   console.error(msg)
  85. }
复制代码
5、创建一个用户登录实体 userInfo.ets

   这个用户实体类包含用户的账号和密码信息,是登录所需
  1. export class UserInfo {
  2.   account: string;
  3.   password: string;
  4.   constructor() {
  5.     this.account = ''
  6.     this.password = ''
  7.   }
  8. }
复制代码
6、创建一个用户API user.ets

   这个API的作用就是统一格式,统一使用【url】、【data】、【method】这三个进行网络请求,也是在请求工具类 HttpRequest.ets 底子上的二次封装
  1. // 这里引入第 4 步创建的请求工具类
  2. import HttpRequest from '../request/HttpRequest'
  3. // 这里引入第 3 步创建的响应体
  4. import { ResponseResult } from '../response/ResponseResult'
  5. // 这里引入第 5 步创建的自定义用户对象,主要用于定义各参数的类型
  6. import { UserInfo } from '../../entity/userInfo'
  7. // 用户登录 API
  8. export function userLogin(params: UserInfo): Promise<ResponseResult> {
  9.   return HttpRequest.request({
  10.     url: '/auth/login',
  11.     data: params,
  12.     method:'POST'
  13.   })
  14. }
复制代码
7、在页面尝试调用 index.ets

   末了在我们的页面启动时直接调用 user.ets 中的 userLogin 方法进行登录测试
  1. // 这里需要引入第 6 步创建的用户API
  2. import { userLogin } from '../common/api/user';
  3. @Entry
  4. @Component
  5. struct Index {
  6.   // 在进入页面时调用 userLogin 接口进行测试
  7.   aboutToAppear(): void {
  8.     userLogin({account: 'admin', password: 'Admin@2024'}).then(res => {
  9.       console.info('页面成功获取到用户信息:' + res.data)
  10.     })
  11.   }
  12.   build() {
  13.     RelativeContainer() {
  14.       
  15.     }
  16.   }
  17. }
复制代码
四、目次布局

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


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

写过一篇

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表