HarmonyOS 简易封装网络请求框架
设计思路
网络请求框架的设计目标是简化 HTTP 请求的发送和响应处理过程。为了实现这一目标,我们定义了几个核心组件:
- IHttpRequest: 定义了发送 HTTP 请求的基本操作,如设置 URL、请求头、请求参数等。
- IHttpListener: 定义了 HTTP 请求完成后的回调方法,用于处理请求的成功和失败事件。
- HttpTask: 封装了 HTTP 请求任务,提供了执行请求和处理响应的功能。
- JsonHttpRequest 和 JsonHttpListener: 分别实现了 IHttpRequest 和 IHttpListener 接口,用于发送和接收 JSON 格式的 HTTP 请求和响应。
- WNetFramework: 提供了静态方法用于发送 HTTP 请求,进一步简化了请求的发送和监听过程。
实现细节
IHttpListener 和 IDataListener 接口
IHttpListener 接口定义了 HTTP 请求完成后的回调方法,包括请求成功和失败的处理。IDataListener 接口扩展了 IHttpListener,添加了对数据操作成功的处理方法。这两个接口的泛型 T 允许处理各种类型的数据,使得监听器能够灵活地处理不同格式的响应。
IHttpListener:
/** * IHttpListener接口定义了HTTP请求完成后的回调方法。 * 实现此接口的监听器将被用于处理HTTP请求的成功和失败事件。 */ export interface IHttpListener { /** * 当HTTP请求成功完成时调用此方法。 * @param result - 请求成功的结果,通常是一个字符串形式的响应数据。 * 根据实际需求,这个结果可能需要进一步解析以获取结构化的数据。 */ onSuccess(result: string): void; /** * 当HTTP请求失败时调用此方法。 * 失败的原因可能包括网络问题、服务器错误、请求超时等。 * 实现此方法的监听器应该能够处理这些错误情况,例如通过显示错误消息或执行回退操作。 */ onFailure(error: any): void; }
IDataListener:
/** * IDataListener接口定义了处理数据成功和失败事件的监听器方法。 * 该接口用于在数据操作(如读取、写入、提交等)完成后进行回调。 * 泛型T表示数据的类型,可以是任何类型,使得监听器能够处理特定类型的数据。 */ export interface IDataListener<T> { /** * 当数据操作成功完成时调用此方法。 * 该方法接收操作结果中的数据作为参数,可以用于更新UI、存储数据或其他操作。 * @param t - 数据操作成功后返回的数据。 */ onSuccess(t: T): void; /** * 当数据操作失败时调用此方法。 * 该方法同样接收可能在操作中返回的数据,可以用来了解失败的原因或进行错误处理。 * @param t - 数据操作失败时返回的数据或错误信息。 */ onFailure(t: any): void; }
HttpTask 类
HttpTask 类封装了 HTTP 请求任务,它接收请求的 URL、请求数据、IHttpRequest 实例和 IHttpListener 实例作为构造函数参数。该类提供了 run 方法用于异步执行 HTTP 请求,并通过 Promise 机制处理请求的完成。
import{ IHttpListener } from'./IHttpListener'; import{ IHttpRequest } from'./IHttpRequest'; /** * HttpTask类用于封装HTTP请求任务,提供执行请求和处理响应的功能。 * 泛型T用于表示请求数据的类型。 */ export class HttpTask<T> { // IHttpRequest类型的私有成员变量,用于发送HTTP请求和接收响应 private iHttpRequest: IHttpRequest; // IHttpListener类型的私有成员变量,用于监听HTTP请求的响应事件 private iHttpListener: IHttpListener; /** * 构造函数接收请求的URL、请求数据、IHttpRequest实例和IHttpListener实例。 * 通过这些参数初始化HttpTask实例,准备发送HTTP请求。 * @param url - 请求的目标URL。 * @param requestData - 要发送的请求数据,可以是任何类型,将被转换为JSON格式。 * @param header - 请求头。 * @param body - 请求体。 * @param iHttpRequest - 实现IHttpRequest接口的请求对象,用于设置请求方法、头信息等。 * @param iHttpListener - 实现IHttpListener接口的监听器对象,用于处理请求的响应。 */ constructor(url: string, header: Record<string, string>, requestData: T, iHttpRequest: IHttpRequest, iHttpListener: IHttpListener) { // 初始化请求对象 this.iHttpRequest = iHttpRequest; // 初始化监听器对象 this.iHttpListener = iHttpListener; // 设置请求的目标URL this.iHttpRequest.setUrl(url); // 将监听器对象绑定到请求对象,以便在请求完成时接收响应 this.iHttpRequest.setListener(iHttpListener); if(header != null) { this.iHttpRequest.setHeader(header) } // 如果提供了请求数据 if(requestData != null) { // 将请求数据转换为JSON字符串格式 let requestParams: string = JSON.stringify(requestData); // 打印请求参数,便于调试 console.log("HttpTask:" + " requestParams:" + requestParams); // 设置请求参数,这些参数将在请求发送时附加到请求体中 this.iHttpRequest.setParams(requestParams); } } static encodeParams(params: { [key: string]: any }): string { let result = Object.keys(params) .map(key => encodeURIComponent(key) + '=' + encodeURIComponent(params[key])) .join('&'); returnresult; } /** * 异步执行HTTP请求的方法。 * 该方法通过调用iHttpRequest的execute方法发送请求,并等待响应。 * 当execute方法返回的Promise被解决时,该方法完成。 * @returns 返回一个Promise<void>,表示异步操作的完成。 */ async run(): Promise<void> { // 调用请求对象的execute方法来发送请求,并等待响应 await this.iHttpRequest.execute(); } }
JsonHttpRequest 和 JsonHttpListener 类
JsonHttpRequest 类实现了 IHttpRequest 接口,用于发送 JSON 格式的 HTTP 请求。它使用 ohos 的 http 模块创建和管理 HTTP 请求,并处理请求结果。JsonHttpListener 类实现了 IHttpListener 接口,将 HTTP 响应结果转换为泛型类型 T 的对象,并将其传递给 IDataListener 接口的实现。
JsonHttpRequest :
importhttp from'@ohos.net.http'; // 引入OhOS的http模块 import{ IHttpListener } from'./IHttpListener'; import{ IHttpRequest } from'./IHttpRequest'; /** * JsonHttpRequest类实现了IHttpRequest接口,用于发送JSON格式的HTTP请求。 * 该类使用OhOS的http模块创建和管理HTTP请求,并处理请求结果。 */ export class JsonHttpRequest implementsIHttpRequest { private url: string = ''; private params: string = ''; private iHttpListener: IHttpListener | null = null; // 存储请求的监听器 private httpRequest: http.HttpRequest | null = null; // 存储OhOS的HttpRequest对象 /** * 构造函数。 */ constructor() { this.httpRequest = http.createHttp(); // 初始化OhOS的HttpRequest对象 } /** * 设置请求的URL。 * @param url - 要请求的资源的URL字符串。 */ setUrl(url: string): void { this.url = url; } /** * 设置请求的参数。 * @param params - 要发送的请求参数。 */ setParams(params: string): void { this.params = params; } /** * 设置请求的监听器。 * @param iHttpListener - 实现IHttpListener接口的监听器对象。 */ setListener(iHttpListener: IHttpListener): void { this.iHttpListener = iHttpListener; } /** * 异步执行HTTP请求的方法。 */ asyncexecute(): Promise<void> { try{ if(!this.url) { throw new Error('URL is not set.'); } if(!this.iHttpListener) { throw new Error('HTTP Listener is not set.'); } console.log('JsonHttpRequest: Sending request to:', this.url); // 使用GET方法发送请求,并将params作为请求体发送 this.httpRequest.request(this.url, { method: http.RequestMethod.GET, extraData: this.params }, (err, data) => { if(err) { // 请求失败,调用监听器的onFailure方法 console.error('JsonHttpRequest: Request failed:', err); this.iHttpListener.onFailure(err); } else{ // 请求成功,调用监听器的onSuccess方法 console.log('JsonHttpRequest: Request successful:', data.result); this.iHttpListener.onSuccess(data.result.toString()); } // 请求完成后,主动销毁请求对象以释放资源 this.httpRequest.destroy(); }); } catch(error) { console.error('JsonHttpRequest: An error occurred:', error); if(this.iHttpListener) { this.iHttpListener.onFailure(error); } } } }
JsonHttpListener :
import{ IDataListener } from'./IDataListener'; import{ IHttpListener } from'./IHttpListener'; /** * JsonHttpListener类实现了IHttpListener接口,用于处理HTTP请求的响应。 * 它将HTTP响应结果转换为泛型类型T的对象,并将其传递给IDataListener接口的实现。 * 泛型T允许处理各种类型的数据,使得监听器能够灵活地处理不同格式的响应。 */ export class JsonHttpListener<T> implements IHttpListener { // 存储IDataListener接口的实现,用于回调数据给调用者 private iDataListener: IDataListener<T>; /** * 构造函数接收一个IDataListener接口的实现。 * @param iDataListener - 实现IDataListener接口的监听器对象。 */ constructor(iDataListener: IDataListener<T>) { this.iDataListener = iDataListener; } /** * 当HTTP请求成功时调用此方法。 * 该方法接收原始的响应字符串,并尝试将其解析为泛型类型T的对象。 * 解析成功后,调用IDataListener的onSuccess方法,并将解析后的对象作为参数传递。 * @param result - HTTP响应的原始字符串。 */ onSuccess(result: string): void { try{ // 尝试将响应字符串解析为泛型类型T的对象 let resultObj: T = JSON.parse(result) asT; // 打印原始响应字符串 console.log("JsonHttpListener result:" + result); // 将解析后的数据通过IDataListener的onSuccess方法回调给调用者 this.iDataListener.onSuccess(resultObj); } catch(error) { // 如果解析失败,打印错误信息并调用onFailure方法 console.error("Error parsing JSON response:", error); // 调用失败处理方法 this.onFailure(error); } } /** * 当HTTP请求失败时调用此方法。 * 由于当前实现中没有处理失败情况的逻辑,所以此方法会抛出一个错误。 * 实际使用时,应根据需要实现失败处理逻辑。 */ onFailure(error: any): void { // 这里可以添加失败处理逻辑,例如记录错误日志或者通知用户 console.error("HTTP request failed:", error.message); if(this.iDataListener) { // 通知IDataListener接口的实现,请求失败 this.iDataListener.onFailure(error); } } }
WNetFramework 类
WNetFramework 类提供了静态方法用于发送 JSON 格式的 HTTP 请求。它通过封装请求任务和监听器,简化了网络请求的发送和处理过程。泛型 T 表示请求参数的类型,而泛型 M 表示响应数据的类型。
importhttp from'@ohos.net.http'; import{ HttpTask } from'./HttpTask'; import{ IDataListener } from'./IDataListener'; import{ IHttpListener } from'./IHttpListener'; import{ IHttpRequest } from'./IHttpRequest'; import{ JsonHttpListener } from'./JsonHttpListener'; import{ JsonHttpRequest } from'./JsonHttpRequest'; /** * JettNetFramework类提供了一个静态方法用于发送JSON格式的HTTP请求。 * 该类通过封装请求任务和监听器,简化了网络请求的发送和处理过程。 * 泛型T表示请求参数的类型,而泛型M表示响应数据的类型。 */ export class WNetFramework<T, M> { /** * 静态方法,用于发送JSON格式的HTTP请求。 * @param url - 请求的目标URL。 * @param header - 请求头。 * @param requestParams - 请求的参数,类型为泛型T。 * @param iDataListener - 实现IDataListener接口的监听器,用于接收请求结果,类型为泛型M。 */ static get<T, M>(url: string, header: Record<string, string>, requestParams: T, iDataListener: IDataListener<M>) { // 创建JsonHttpRequest对象,用于发送HTTP请求 let iHttpRequest: IHttpRequest = new JsonHttpRequest(); // 创建JsonHttpListener对象,用于处理HTTP请求的响应 let iHttpListener: IHttpListener = new JsonHttpListener<M>(iDataListener); // 创建HttpTask对象,封装请求任务 let httpTask: HttpTask<T> = new HttpTask(url, header, requestParams, iHttpRequest, iHttpListener); // 执行请求任务 httpTask.run().catch(error => { // 调用监听器的onFailure方法,通知请求失败 iDataListener.onFailure(error); }); } staticpost<T, M>(url: string, header: Record<string, string>, requestParams: T, iDataListener: IDataListener<M>) { // 创建JsonHttpRequest对象,用于发送HTTP请求 let iHttpRequest: IHttpRequest = newJsonHttpRequest(); iHttpRequest.setRequestMethod(http.RequestMethod.POST) // 创建JsonHttpListener对象,用于处理HTTP请求的响应 let iHttpListener: IHttpListener = newJsonHttpListener<M>(iDataListener); // 创建HttpTask对象,封装请求任务 let httpTask: HttpTask<T> = newHttpTask(url, header, requestParams, iHttpRequest, iHttpListener); // 执行请求任务 httpTask.run().catch(error => { // 调用监听器的onFailure方法,通知请求失败 iDataListener.onFailure(error); }); } }
使用示例
以下是一个使用 WNetFramework 发送 GET 请求的示例:
WNetFramework.get<RequestBean, WeatherResponse>(url, headers, null, { onSuccess(result: WeatherResponse) { console.log("WNetFramework: onSuccess(result:ResponceBean)==>>" + JSON.stringify(result.result)); }, onFailure(error) { console.log("WNetFramework: onFailure(msg)==>>" + JSON.stringify(error.message)); } });
总结
通过封装网络请求处理框架,我们可以大大简化网络请求的发送和响应处理过程。本框架的设计和实现展示了如何使用 TypeScript 的泛型和接口来创建灵活且可扩展的代码。提高开发效率,使代码更加易于维护和扩展。