HarmonyOS HTTP網(wǎng)絡(luò)請(qǐng)求(-)

Demo地址:https://gitee.com/hyhe/httpLibraryDemo.git
加解密、https認(rèn)證在HarmonyOS HTTP網(wǎng)絡(luò)請(qǐng)求(二)中做處理

一、框架說(shuō)明

http請(qǐng)求框架說(shuō)明.png

1. 功能說(shuō)明

DecryptionResponseParam: 數(shù)據(jù)解密處理 待實(shí)現(xiàn)
EncryptionRequestParam: 數(shù)據(jù)加密處理 待實(shí)現(xiàn)
PrettyPrint: 日志打印處理
RequestApi: api列表
RequestAuthenHandler: 認(rèn)證處理 待實(shí)現(xiàn)
RequestConfiguration: 配置RequestOption
HttpManager: 請(qǐng)求管理類
RequestImplement: 請(qǐng)求實(shí)現(xiàn)類
RequestMethod: 請(qǐng)求方法枚舉
RequestOption: 自定義RequestOption類
RequestTools: http模塊工具類
ResponseHandler: 請(qǐng)求結(jié)果處理類
ResponseModel: 最終返回業(yè)務(wù)層數(shù)據(jù)模型

二买鸽、核心類說(shuō)明

1. 請(qǐng)求RequestOption類

export class RequestOption {
  /**
   * 請(qǐng)求host
   * 如果特定接口需要更換域名查剖,請(qǐng)傳入
   */
  host?: string;

  /**
   * url: 請(qǐng)求接口名
   */
  url?: string;

  /**
   * method: RequestMethod 請(qǐng)求方法
   */
  methodType?: RequestMethod;

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

  /**
   * queryParams: 請(qǐng)求參數(shù)
   */
  queryParams?: Record<string, any>;

  /**
   * Additional data of the request.
   * extraData: 當(dāng)使用POST請(qǐng)求時(shí)此字段用于傳遞內(nèi)容
   */
  extraData?: Record<string, any>;

  /**
   * encryptionParam: 加密后的參數(shù)
   */
  encryptionParam?: Record<string, any>;

  /**
   * expectDataType
   * 指定返回?cái)?shù)據(jù)的類型。如果設(shè)置了此參數(shù)鞭光,系統(tǒng)將優(yōu)先返回指定的類型
   */
  expectDataType?: http.HttpDataType = http.HttpDataType.OBJECT;

  /**
   * usingCache
   * 是否使用緩存吏廉,默認(rèn)為true。
   * */
  usingCache?: boolean = false

  /**
   * priority
   * 優(yōu)先級(jí)惰许,范圍[1,1000]席覆,默認(rèn)是1
   * */
  priority?: number = 1

  /**
   * readTimeout
   * 讀取超時(shí)時(shí)間。單位為毫秒(ms)汹买,默認(rèn)為60000ms娜睛。
   * 設(shè)置為0表示不會(huì)出現(xiàn)超時(shí)情況
   * */
  readTimeout?: number = 60000

  /**
   * connectionTimeOut
   * 連接超時(shí)時(shí)間。單位為毫秒(ms)卦睹,默認(rèn)為60000ms
   * */
  connectionTimeOut?: number = 60000

  /**
   * usingProtocol
   * 使用協(xié)議畦戒。默認(rèn)值由系統(tǒng)自動(dòng)指定。
   * */
  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, // 可選结序,默認(rèn)為http.RequestMethod.GET
      // 開發(fā)者根據(jù)自身業(yè)務(wù)需要添加header字段
      header: this.dealHeader(requestOption.header),
      // query請(qǐng)求參數(shù)
      queryParams: this.dealParam(requestOption.queryParams),
      // 當(dāng)使用POST請(qǐng)求時(shí)此字段用于傳遞內(nèi)容
      extraData: this.dealExtraData(requestOption.extraData),
      encryptionParam: this.encryptionParam(requestOption.extraData),
      expectDataType: requestOption.expectDataType, // 可選障斋,指定返回?cái)?shù)據(jù)的類型
      usingCache: requestOption.usingCache, // 可選,默認(rèn)為true
      priority: requestOption.priority, // 可選徐鹤,默認(rèn)為1
      readTimeout: requestOption.readTimeout, // 可選垃环,默認(rèn)為60000ms
      connectTimeout: requestOption.connectionTimeOut, // 可選,默認(rèn)為60000ms
      usingProtocol: requestOption.usingProtocol, // 可選返敬,協(xié)議類型默認(rèn)值由系統(tǒng)自動(dòng)指定
    };
  }

  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> {
    // 對(duì)參數(shù)進(jìn)行加密處理
    return {}
  }
}

3. 網(wǎng)絡(luò)請(qǐng)求方法枚舉RequestMethod

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

4. 請(qǐng)求管理類 HttpManager

export class HttpManager {
  /**
   * 發(fā)送請(qǐng)求
   * @param RequestOptions
   * @return Promise
   */
  static requestApi<T>(requestOption: RequestOption): Promise<ResponseModel<T>> {
    // 網(wǎng)絡(luò)請(qǐng)求中遂庄,可以在此處理requestOption
    return RequestImplement.requestApi<T>(requestOption);
  }
}

5. 實(shí)際請(qǐng)求類 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;

      // 每一個(gè)httpRequest對(duì)應(yīng)一個(gè)HTTP請(qǐng)求任務(wù),不可復(fù)用
      let httpRequest = http.createHttp();
      // 用于訂閱HTTP響應(yīng)頭劲赠,此接口會(huì)比request請(qǐng)求先返回涛目。可以根據(jù)業(yè)務(wù)需要訂閱此消息
      // 從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請(qǐng)求的URL地址,可以帶參數(shù)也可以不帶參數(shù)塑煎。URL地址需要開發(fā)者自定義沫换。請(qǐng)求的參數(shù)可以在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響應(yīng)頭事件
            // httpRequest.off('headersReceive');
            // 當(dāng)該請(qǐng)求使用完畢時(shí),調(diào)用destroy方法主動(dòng)銷毀
            // httpRequest.destroy();
            resModel = new ResponseModel(err.message, err.code, false, "", null);
            resolveFunction(resModel)
          }
          PrettyPrint.printRequestLog(requestOption, resModel)
        });
    })
  }
}

6. 請(qǐng)求結(jié)果處理類 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 {
      // 請(qǐng)求失敗
      responseModel.msg = 'request fail'
      reBackResponseModel(responseModel)
    }
  }
}

7.請(qǐng)求結(jié)果處理后返回?cái)?shù)據(jù)模型

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. 網(wǎng)絡(luò)請(qǐng)求工具類

 /// 日志打印不全處理
  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. 請(qǐng)求日志打印類

export class PrettyPrint {
  static printRequestLog<T>(requestOption: RequestOption, responseModel: ResponseModel<T>) {
    console.log("");
    console.log(
      "????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????");
    console.log("?????????????? ------  請(qǐng)求開始  ------ ??????????????");
    console.log("請(qǐng)求接口名:");
    console.log("url = " + requestOption.url);

    console.log("請(qǐng)求頭參數(shù):");
    console.log("headers = " + JSON.stringify(requestOption.header));

    console.log("初始參數(shù):");
    console.log("incomeParam = " + JSON.stringify(requestOption.queryParams));
    console.log("incomeExtraData = " + JSON.stringify(requestOption.extraData));

    console.log("加密請(qǐng)求參數(shù):");
    console.log("encryptionParam = " + JSON.stringify(requestOption.encryptionParam));

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

    console.log("?????????????? ------  請(qǐng)求結(jié)束  ------ ??????????????");
    console.log(
      "???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????");
  }
}

10. 本文以HAR模式實(shí)現(xiàn)

在index.ets中導(dǎo)出兩個(gè)類

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

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

三最铁、請(qǐng)求示例

static getHomeAdvertisementData(reBack: (models: Array<CAHomeAdvModel>, error: BaseError) => void) {
// 配置請(qǐng)求參數(shù)
   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("請(qǐng)求結(jié)果: " + JSON.stringify(responseModel))
          }).catch((error: BaseError) => {
            console.log("失敗信息:" + JSON.stringify(error))
          })
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末讯赏,一起剝皮案震驚了整個(gè)濱河市垮兑,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌漱挎,老刑警劉巖甥角,帶你破解...
    沈念sama閱讀 221,198評(píng)論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異识樱,居然都是意外死亡嗤无,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門怜庸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)当犯,“玉大人,你說(shuō)我怎么就攤上這事割疾『课溃” “怎么了?”我有些...
    開封第一講書人閱讀 167,643評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵宏榕,是天一觀的道長(zhǎng)拓诸。 經(jīng)常有香客問(wèn)我,道長(zhǎng)麻昼,這世上最難降的妖魔是什么奠支? 我笑而不...
    開封第一講書人閱讀 59,495評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮抚芦,結(jié)果婚禮上倍谜,老公的妹妹穿的比我還像新娘。我一直安慰自己叉抡,他們只是感情好尔崔,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著褥民,像睡著了一般季春。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上消返,一...
    開封第一講書人閱讀 52,156評(píng)論 1 308
  • 那天载弄,我揣著相機(jī)與錄音,去河邊找鬼侦副。 笑死侦锯,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的秦驯。 我是一名探鬼主播,決...
    沈念sama閱讀 40,743評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼挣棕,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼译隘!你這毒婦竟也來(lái)了亲桥?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,659評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤固耘,失蹤者是張志新(化名)和其女友劉穎题篷,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體厅目,經(jīng)...
    沈念sama閱讀 46,200評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡番枚,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了损敷。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片葫笼。...
    茶點(diǎn)故事閱讀 40,424評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖拗馒,靈堂內(nèi)的尸體忽然破棺而出路星,到底是詐尸還是另有隱情,我是刑警寧澤诱桂,帶...
    沈念sama閱讀 36,107評(píng)論 5 349
  • 正文 年R本政府宣布洋丐,位于F島的核電站,受9級(jí)特大地震影響挥等,放射性物質(zhì)發(fā)生泄漏友绝。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評(píng)論 3 333
  • 文/蒙蒙 一肝劲、第九天 我趴在偏房一處隱蔽的房頂上張望九榔。 院中可真熱鬧,春花似錦涡相、人聲如沸哲泊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)切威。三九已至,卻和暖如春丙号,著一層夾襖步出監(jiān)牢的瞬間先朦,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工犬缨, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留喳魏,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,798評(píng)論 3 376
  • 正文 我出身青樓怀薛,卻偏偏與公主長(zhǎng)得像刺彩,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容