HarmonyOS 鸿蒙网络层封装实践:构建稳健的HTTP请求客户端

引言

在鸿蒙(HarmonyOS)应用开发中,网络通信是实现数据交互的核心能力。优雅的网络层封装不仅能提升代码的可维护性和复用性,还能统一异常处理机制,为后续的业务扩展奠定坚实基础。本文将通过一个实战案例,详细介绍如何构建一个功能完备、易于使用的网络请求客户端。

一、核心设计理念

1.1 架构设计原则

在开始编码之前,我们确立了以下设计原则:

  1. 单一职责:网络层专注于HTTP通信,业务逻辑与数据转换分离
  2. 开闭原则:支持扩展新的HTTP方法,无需修改现有代码
  3. 接口隔离:提供简洁的API,隐藏底层实现复杂性

1.2 技术栈选择

  • 基础框架 :鸿蒙官方@kit.NetworkKit模块,提供原生HTTP能力
  • 设计模式:采用单例模式,确保全局配置一致性

二、网络层实现细节

2.1 数据类型定义

typescript 复制代码
/**
 * 标准API响应结构定义
 * @property code - 业务状态码(如:"000000"表示成功)
 * @property message - 服务器返回的业务提示信息
 * @property data - 实际返回的业务数据内容
 */
export interface MyResponseType {
  code: string;
  message: string;
  data: string;
}

这一接口定义不仅规范了前后端数据契约,还为TypeScript提供了完整的类型提示,确保开发过程中及早发现类型不匹配问题。

2.2 HttpClient核心实现

typescript 复制代码
/**
 * HTTP客户端(单例模式)
 * 封装HTTP请求方法,提供类型安全的请求接口
 */
export class HttpClient {
  private static instance: HttpClient;
  
  // API服务端基础地址
  private baseUrl: string = 'https://xxx.xxxx.xxxx.xxxx:xxxx/';
  
  // 默认请求头配置
  private headers: Record<string, string> = {
    'Content-Type': 'application/json',  // 指定请求体为JSON格式
    'User-Agent': 'HarmonyOS-App'        // 标识客户端类型,便于服务端统计
  };

  /**
   * 获取HttpClient单例实例
   * @returns 全局唯一的HttpClient实例
   * @example
   * const client = HttpClient.getInstance();
   */
  static getInstance(): HttpClient {
    if (!HttpClient.instance) {
      HttpClient.instance = new HttpClient(); // 首次调用时创建实例
    }
    return HttpClient.instance;
  }

  // 私有构造函数,防止外部实例化
  private constructor() {}
}

2.3 核心请求方法实现

typescript 复制代码
/**
 * 通用HTTP请求方法
 * @param method - HTTP方法(GET、POST等)
 * @param url - 请求地址(相对路径或完整URL)
 * @param data - 请求体数据
 * @returns 解析后的响应数据
 */
private async request<T>(method: http.RequestMethod, url: string, data?: string): Promise<T> {
  const httpRequest = http.createHttp();
  
  // 智能URL拼接:支持绝对路径和相对路径
  const fullUrl = url.startsWith('http') ? url : `${this.baseUrl}${url}`;

  try {
    // 发起网络请求
    const response = await httpRequest.request(fullUrl, {
      method,
      header: this.headers,
      extraData: data ? JSON.stringify(data) : undefined
    });

    // HTTP状态码校验(2xx视为成功)
    if (response.responseCode >= 200 && response.responseCode < 300) {
      return JSON.parse(response.result as string);
    } else {
      // 非2xx状态码抛出异常
      throw new Error(`HTTP ${response.responseCode}: ${response.result}`);
    }
  } catch (error) {
    // 统一异常转换和处理
    const err = error as BusinessError;
    console.error(`请求失败: ${err.code} ${err.message}`);
    throw new Error(`HTTP ${error}`);
  } finally {
    // 确保网络资源释放
    httpRequest.destroy();
  }
}

2.4 便捷方法封装

typescript 复制代码
/**
 * POST请求快捷方法
 * @param endpoint - API端点路径
 * @param body - 请求体对象
 * @returns Promise解析后的响应数据
 * @example
 * client.post<ResponseType, RequestBody>('api/login', {username: 'test'});
 */
async post<T, U>(endpoint: string, body: U): Promise<T> {
  // 自动序列化请求体为JSON字符串
  return this.request(http.RequestMethod.POST, endpoint, JSON.stringify(body));
}

泛型参数设计

  • T:指定响应数据类型,提供编译时类型安全
  • U:指定请求体类型,确保请求数据结构正确性

三、业务层调用示例

3.1 页面调用实现

typescript 复制代码
/**
 * 处理网络请求的异步方法
 */
private async handleRequest() {
  try {
    // 获取HttpClient单例实例
    const client = HttpClient.getInstance();
    
    // 发起POST请求,指定响应类型为MyResponseType,请求体类型为string
    const response = await client.post<MyResponseType, string>('baidu/wenxin', '你好');

    // 调试输出:便于开发阶段验证数据格式
    console.log("请求结果:");
    console.log(JSON.stringify(response));
    
    // 典型响应示例:
    // {
    //   "code": "000000",
    //   "msg": "请求成功",
    //   "data": "您好!有什么我可以帮助您的吗?"
    // }
  } catch (error) {
    // 统一错误处理:日志记录和用户提示
    console.error('请求失败:', error);
    this.message = '请求异常';
  }
}

完整代码

ts 复制代码
import { http } from '@kit.NetworkKit'; // 导入新版网络模块
import { BusinessError } from '@kit.BasicServicesKit';

/**
 * 定义标准API响应结构
 * @property code - 响应状态码(如:200成功,500服务器错误)
 * @property message - 服务器返回的提示信息
 * @property data - 实际返回的业务数据内容
 */
export interface MyResponseType {
  code: string;
  message: string;
  data: string;
}

/**
 * HttpClient网络请求客户端(单例模式)
 * 封装HTTP请求方法,提供POST请求的快捷方式
 */
export class HttpClient {
  private static instance: HttpClient; // 单例实例
  // API基础地址
  private baseUrl: string = 'https://xxx.xxxx.xxxx.xxxx:xxxx/';
  // 默认请求头配置
  private headers: Record<string, string> = {
    'Content-Type': 'application/json', // 请求体格式为JSON
    'User-Agent': 'HarmonyOS-App'       // 标识客户端类型
  };

  /**
   * 获取HttpClient单例实例
   * @returns 全局唯一的HttpClient实例
   * @example
   * const client = HttpClient.getInstance();
   */
  static getInstance(): HttpClient {
    if (!HttpClient.instance) {
      HttpClient.instance = new HttpClient(); // 懒加载创建实例
    }
    return HttpClient.instance;
  }

  // 通用请求方法
  private async request<T>(method: http.RequestMethod, url: string, data?: string): Promise<T> {
    const httpRequest = http.createHttp();
    const fullUrl = url.startsWith('http') ? url : `${this.baseUrl}${url}`;

    try {
      const response = await httpRequest.request(fullUrl, {
        method,
        header: this.headers,
        extraData: data ? JSON.stringify(data) : undefined
      });

      if (response.responseCode >= 200 && response.responseCode < 300) {
        return JSON.parse(response.result as string);
      } else {
        throw new Error(`HTTP ${response.responseCode}: ${response.result}`);
      }
    } catch (error) {
      const err = error as BusinessError;
      console.error(`请求失败: ${err.code} ${err.message}`);
      throw new Error(`HTTP ${error}`);
    } finally {
      httpRequest.destroy();
    }
  }

  /**
   * 发送POST请求的快捷方法
   * @param endpoint - 接口端点路径(如:'user/login')
   * @param body - 请求体对象(自动序列化为JSON)
   * @returns Promise解析后的响应数据
   * @example
   * client.post<ResponseType, RequestBody>('api/login', {username: 'test'});
   */
  async post<T, U>(endpoint: string, body: U): Promise<T> {
    return this.request(http.RequestMethod.POST, endpoint, JSON.stringify(body));
  }

}
相关推荐
lbb 小魔仙2 小时前
【HarmonyOS】React Native实战项目+输入格式化掩码Hook
react native·华为·harmonyos
lbb 小魔仙2 小时前
【HarmonyOS】React Native实战项目+关键词高亮搜索Hook
react native·华为·harmonyos
果粒蹬i2 小时前
【HarmonyOS】RN of HarmonyOS实战开发项目+React数据管理方案
react.js·华为·harmonyos
早點睡3902 小时前
基础入门 Flutter for OpenHarmony:FloatingActionButton 浮动按钮详解
flutter·harmonyos
●VON3 小时前
HarmonyOS应用开发实战(基础篇)Day04-《泛型与空值安全》
安全·华为·harmonyos·鸿蒙·von
左手厨刀右手茼蒿3 小时前
Flutter for OpenHarmony 实战:DartX — 极致简练的开发超能力集
android·flutter·ui·华为·harmonyos
空白诗3 小时前
基础入门 Flutter for OpenHarmony:TabBar 标签栏组件详解
flutter·harmonyos
早點睡3903 小时前
基础入门 Flutter for OpenHarmony:RefreshIndicator 下拉刷新详解
flutter·harmonyos
破烂pan3 小时前
Python 实现 HTTP Client 的常见方式
开发语言·python·http