HarmonyOS HTTP网络请求(-)

Demo地址:https://gitee.com/hyhe/httpLibraryDemo.git
加解密、https认证在HarmonyOS HTTP网络请求(二)中做处理

一、框架说明

http请求框架说明.png

1. 功能说明

DecryptionResponseParam: 数据解密处理 待实现
EncryptionRequestParam: 数据加密处理 待实现
PrettyPrint: 日志打印处理
RequestApi: api列表
RequestAuthenHandler: 认证处理 待实现
RequestConfiguration: 配置RequestOption
HttpManager: 请求管理类
RequestImplement: 请求实现类
RequestMethod: 请求方法枚举
RequestOption: 自定义RequestOption类
RequestTools: http模块工具类
ResponseHandler: 请求结果处理类
ResponseModel: 最终返回业务层数据模型

二、核心类说明

1. 请求RequestOption类

export class RequestOption {
  /**
   * 请求host
   * 如果特定接口需要更换域名,请传入
   */
  host?: string;

  /**
   * url: 请求接口名
   */
  url?: string;

  /**
   * method: RequestMethod 请求方法
   */
  methodType?: RequestMethod;

  /**
   *
   * */
  header?: Record<string, any>;

  /**
   * queryParams: 请求参数
   */
  queryParams?: Record<string, any>;

  /**
   * Additional data of the request.
   * extraData: 当使用POST请求时此字段用于传递内容
   */
  extraData?: Record<string, any>;

  /**
   * encryptionParam: 加密后的参数
   */
  encryptionParam?: Record<string, any>;

  /**
   * expectDataType
   * 指定返回数据的类型。如果设置了此参数,系统将优先返回指定的类型
   */
  expectDataType?: http.HttpDataType = http.HttpDataType.OBJECT;

  /**
   * usingCache
   * 是否使用缓存,默认为true。
   * */
  usingCache?: boolean = false

  /**
   * priority
   * 优先级,范围[1,1000],默认是1
   * */
  priority?: number = 1

  /**
   * readTimeout
   * 读取超时时间。单位为毫秒(ms),默认为60000ms。
   * 设置为0表示不会出现超时情况
   * */
  readTimeout?: number = 60000

  /**
   * connectionTimeOut
   * 连接超时时间。单位为毫秒(ms),默认为60000ms
   * */
  connectionTimeOut?: number = 60000

  /**
   * usingProtocol
   * 使用协议。默认值由系统自动指定。
   * */
  usingProtocol?: http.HttpProtocol = http.HttpProtocol.HTTP1_1
}

2. RequestConfiguration

export class RequestConfiguration {
  static configurationRequestOptions(requestOption: RequestOption): Record<string, any> {

    return {
      url: requestOption.host + requestOption.url,
      method: requestOption.methodType, // 可选,默认为http.RequestMethod.GET
      // 开发者根据自身业务需要添加header字段
      header: this.dealHeader(requestOption.header),
      // query请求参数
      queryParams: this.dealParam(requestOption.queryParams),
      // 当使用POST请求时此字段用于传递内容
      extraData: this.dealExtraData(requestOption.extraData),
      encryptionParam: this.encryptionParam(requestOption.extraData),
      expectDataType: requestOption.expectDataType, // 可选,指定返回数据的类型
      usingCache: requestOption.usingCache, // 可选,默认为true
      priority: requestOption.priority, // 可选,默认为1
      readTimeout: requestOption.readTimeout, // 可选,默认为60000ms
      connectTimeout: requestOption.connectionTimeOut, // 可选,默认为60000ms
      usingProtocol: requestOption.usingProtocol, // 可选,协议类型默认值由系统自动指定
    };
  }

  static setCookie(): Record<string, any> {
    return []
  }

  static isValidUrl(): Boolean {
    return true
  }

  static dealHeader(header: Record<string, any>): Record<string, any> {
    var newHeader = header ?? {}
    newHeader["Content-Type"] = "application/json"
    return newHeader
  }

  static dealParam(param: Record<string, any>): Record<string, any> {
    var newParam = param ?? {}
    return newParam
  }

  static dealExtraData(extraData: Record<string, any>): Record<string, any> {
    var newExtraData = extraData ?? {}
    return newExtraData
  }

  static encryptionParam(extraParam: Record<string, any>): Record<string, any> {
    // 对参数进行加密处理
    return {}
  }
}

3. 网络请求方法枚举RequestMethod

export enum RequestMethod {
  GET = "GET",
  POST = "POST",
  OPTIONS = "OPTIONS",
  HEAD = "HEAD",
  PUT = "PUT",
  DELETE = "DELETE",
  TRACE = "TRANCE",
  CONNECT = "CONNECT"
}

4. 请求管理类 HttpManager

export class HttpManager {
  /**
   * 发送请求
   * @param RequestOptions
   * @return Promise
   */
  static requestApi<T>(requestOption: RequestOption): Promise<ResponseModel<T>> {
    // 网络请求中,可以在此处理requestOption
    return RequestImplement.requestApi<T>(requestOption);
  }
}

5. 实际请求类 RequestImplement

export class RequestImplement {
  static requestApi<T>(requestOption: RequestOption): Promise<ResponseModel<T>> {
    return new Promise<ResponseModel<T>>((resolve, reject) => {
      let resolveFunction = resolve;
      let rejectFunction = reject;

      // 每一个httpRequest对应一个HTTP请求任务,不可复用
      let httpRequest = http.createHttp();
      // 用于订阅HTTP响应头,此接口会比request请求先返回。可以根据业务需要订阅此消息
      // 从API 8开始,使用on('headersReceive', Callback)替代on('headerReceive', AsyncCallback)。 8+
      httpRequest.on('headersReceive', (header) => {
        console.info('header: ' + JSON.stringify(header));
      });
      var resModel: ResponseModel<T>
      console.log(JSON.stringify(RequestConfiguration.configurationRequestOptions(requestOption)))
      let configuration = RequestConfiguration.configurationRequestOptions(requestOption)
      httpRequest.request(
        // 填写HTTP请求的URL地址,可以带参数也可以不带参数。URL地址需要开发者自定义。请求的参数可以在extraData中指定
        configuration.url,
        configuration,
        (err, response) => {
          if (!err) {
            ResponseHandler.responseHandler<T>(configuration.url, response, (responseModel) => {
              resModel = responseModel as ResponseModel<T>
              if (responseModel.isSuccess) {
                resolveFunction(responseModel)
              } else {
                rejectFunction(responseModel)
              }
            })
          } else {
            console.info('error:' + JSON.stringify(err));
            // // 取消订阅HTTP响应头事件
            // httpRequest.off('headersReceive');
            // 当该请求使用完毕时,调用destroy方法主动销毁
            // httpRequest.destroy();
            resModel = new ResponseModel(err.message, err.code, false, "", null);
            resolveFunction(resModel)
          }
          PrettyPrint.printRequestLog(requestOption, resModel)
        });
    })
  }
}

6. 请求结果处理类 ResponseHandler

export class ResponseHandler {
  static responseHandler<T>(url: String, response: http.HttpResponse, reBackResponseModel: (responseModel: ResponseModel<T>) => void ): void {
    let responseModel: ResponseModel<T> = new ResponseModel("", 10000, false, "", null);
    // 需要处理Url
    if (url == "") {
      return
    }

    if (http.ResponseCode.OK == response.responseCode) {
      responseModel.data = JSON.stringify(response.result)
      console.log(`typeof=====${typeof response.result}`)
      let tModel: T = JSON.parse(JSON.stringify(response.result));
      if (tModel) {
        responseModel.msgCode = 200
        responseModel.isSuccess = true
        responseModel.resultModel = tModel
      } else {
        responseModel.msgCode = response.result["code"]
        responseModel.msg = response.result["message"]
      }
      reBackResponseModel(responseModel)
    } else {
      // 请求失败
      responseModel.msg = 'request fail'
      reBackResponseModel(responseModel)
    }
  }
}

7.请求结果处理后返回数据模型

export class ResponseModel<T> {
  msg?: string
  msgCode?: number
  isSuccess?: Boolean
  data?: string | Object | ArrayBuffer
  resultModel?: T

  constructor(msg: string = "", msgCode: number = 10000, isSuccess: Boolean = false, data: string = "", resultModel: T) {
    this.msg = msg
    this.msgCode = msgCode
    this.isSuccess = isSuccess
    this.data = data
    this.resultModel = resultModel
  }

  responseIsSuccess(): Boolean {
    return this.isSuccess ?? false
  }
}

8. 网络请求工具类

 /// 日志打印不全处理
  static printLongLog(message: string) {
    let maxLogSize = 400
    for (let i = 0; i < message.length / maxLogSize; i++) {
      let start = i * maxLogSize
      let end = (i + 1) * maxLogSize
      end = end > message.length ? message.length : end
      console.log(message.substring(start, end))
    }
  }
}

9. 请求日志打印类

export class PrettyPrint {
  static printRequestLog<T>(requestOption: RequestOption, responseModel: ResponseModel<T>) {
    console.log("");
    console.log(
      "࿐₅₂ₒ࿐₅₂ₒ࿐₅₂ₒ࿐₅₂ₒ࿐₅₂ₒ࿐₅₂ₒ࿐₅₂ₒ࿐₅₂ₒ࿐₅₂ₒ࿐₅₂ₒ࿐₅₂ₒ࿐₅₂ₒ࿐₅₂ₒ࿐₅₂ₒ࿐₅₂ₒ࿐₅₂ₒ࿐₅₂ₒ࿐₅₂ₒ࿐₅₂ₒ࿐₅₂ₒ࿐₅₂ₒ࿐₅₂ₒ࿐₅₂ₒ࿐₅₂ₒ࿐₅₂ₒ࿐₅₂ₒ࿐₅₂ₒ࿐₅₂ₒ࿐₅₂ₒ࿐₅₂ₒ࿐₅₂ₒ࿐₅₂ₒ࿐₅₂ₒ࿐₅₂ₒ࿐₅₂ₒ࿐₅₂ₒ࿐₅₂ₒ࿐₅₂ₒ");
    console.log("࿐࿐࿐࿐࿐࿐࿐࿐࿐࿐࿐࿐࿐࿐ ------  请求开始  ------ ࿐࿐࿐࿐࿐࿐࿐࿐࿐࿐࿐࿐࿐࿐");
    console.log("请求接口名:");
    console.log("url = " + requestOption.url);

    console.log("请求头参数:");
    console.log("headers = " + JSON.stringify(requestOption.header));

    console.log("初始参数:");
    console.log("incomeParam = " + JSON.stringify(requestOption.queryParams));
    console.log("incomeExtraData = " + JSON.stringify(requestOption.extraData));

    console.log("加密请求参数:");
    console.log("encryptionParam = " + JSON.stringify(requestOption.encryptionParam));

    if (responseModel?.isSuccess) {
      console.log("返回结果:");
      console.log("response = ")
      RequestTools.printLongLog(responseModel.data.toString())
    } else {
      console.log("失败日志:");
      console.log("errorInfo = " + responseModel?.msgCode + responseModel?.msg);
    }

    console.log("࿐࿐࿐࿐࿐࿐࿐࿐࿐࿐࿐࿐࿐࿐ ------  请求结束  ------ ࿐࿐࿐࿐࿐࿐࿐࿐࿐࿐࿐࿐࿐࿐");
    console.log(
      "༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄༄");
  }
}

10. 本文以HAR模式实现

在index.ets中导出两个类

export { HttpManager } from './src/main/ets/http/RequestHttpManager'

export { RequestMethod } from './src/main/ets/http/RequestMethod'

三、请求示例

static getHomeAdvertisementData(reBack: (models: Array<CAHomeAdvModel>, error: BaseError) => void) {
// 配置请求参数
   let param: Record<string, string> = { "aa": "1", "bb": "0" }
          HttpManager.requestApi<ResultBaseModel<Array<CAHomeAdvModel>>>({
            host: "你的host: http://domain",
            url: "接口名",
            methodType: RequestMethod.POST,
            extraData: param
          }).then((responseModel) => {
            console.log("请求结果: " + JSON.stringify(responseModel))
          }).catch((error: BaseError) => {
            console.log("失败信息:" + JSON.stringify(error))
          })
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容