Harmony OS Next 開發(fā)【HttpRequest 網(wǎng)絡(luò)請求封裝】

官方的 ArkTs 已經(jīng)提供了 @ohos.net.http (數(shù)據(jù)請求) 庫趟咆,并且支持常見的GET、POST梅屉、OPTIONS值纱、HEAD、PUT坯汤、DELETE计雌、TRACE、CONNECT方法玫霎,大多數(shù) App 或者元服務(wù)都能滿足

本文也是對官方網(wǎng)絡(luò)請求庫,進(jìn)行二次封裝妈橄,滿足自己一些特定場景的需要

一庶近、創(chuàng)建 NetWorkManage 實(shí)例

這里主要提供 2 個能力:

  1. 設(shè)置 BaseUrl,當(dāng)然也支持 path 參數(shù)傳 "http:host/path" 完整的鏈路請求眷蚓,兼容多域名應(yīng)用
  2. 配置默認(rèn)的 Content-type鼻种、connectTimeout、readTimeout
class NetWorkManage {  
  private BASE_URL: string = ''  
  private requestOption: RequestOption = { method: http.RequestMethod.GET, path: '' }  
  
  setBaseUrl(url: string) {  
    this.BASE_URL = url  
  }  
  
  createRequest(requestOption: RequestOption): NetWorkManage {  
    if (!this.BASE_URL) {  
      throw Error('BaseUrl not null')  
    }  
    let requestConfig = requestOption  
    let headers: Record<string, string> = requestOption.header || {}  
    if (!headers['Content-type']) {  
      headers['Content-type'] = ContentType.JSON  
    }  
    requestConfig.header = headers  
    this.requestOption = requestConfig  
    return this  
  }
}

二沙热、添加攔截器

主要涉及到一些對公共 header 處理叉钥,如傳遞用戶 Token等,或者對 data 進(jìn)行二次封裝篙贸,具體依自身業(yè)務(wù)需要來

DefaultHeadersInterceptor 為默認(rèn)的攔截器示例投队,開發(fā)者可以自行修改其中內(nèi)容

InterceptUtil.ets 攔截器類

// 攔截器接口
export interface HttpInterceptor {  
  intercept: (options: http.HttpRequestOptions) => http.HttpRequestOptions  
}  

// 默認(rèn)攔截器,可自行修改爵川,下面提供了對請求heade修改的示例
export class DefaultHeadersInterceptor implements HttpInterceptor {  
  intercept(options: http.HttpRequestOptions) {  
    let headers: Record<string, string> = options.header as Record<string, string>  
    headers.test1 = 'test'  
    return options  
  }    
}

NetWorkManage.ets  請求工具類

// 聲明攔截器數(shù)組
private REQUEST_INTERCEPTORS: Array<HttpInterceptor> = [new DefaultHeadersInterceptor()]

// 添加攔截器
addRequestInterceptor(interceptor: HttpInterceptor) {  
  this.REQUEST_INTERCEPTORS.push(interceptor)  
}

三敷鸦、響應(yīng)攔截器

可以模仿請求攔截器,再單獨(dú)實(shí)現(xiàn)一套響應(yīng)攔截器寝贡,對統(tǒng)一的請求數(shù)據(jù)進(jìn)行處理扒披,但是我們業(yè)務(wù)不太需要,可以自行實(shí)現(xiàn)

InterceptUtil.ets 攔截器類
// 攔截器接口
export interface HttpResponseInterceptor {  
  intercept: (data: http.HttpResponse) => http.HttpResponse  
}

export class DefaultResponseInterceptor implements HttpResponseInterceptor {  
  intercept(data: http.HttpResponse){  
    // 對 data 進(jìn)行錯誤類型統(tǒng)一處理  
    return data  
  }  
}


NetWorkManage.ets  請求工具類

// 聲明響應(yīng)攔截器數(shù)組
private RESPONSE_INTERCEPTORS: Array<HttpInterceptor> = [new DefaultHeadersInterceptor()]

// 添加攔截器
addResponseInterceptor(interceptor: HttpInterceptor) {  
  this.RESPONSE_INTERCEPTORS.push(interceptor)  
}

四圃泡、使用泛型對數(shù)據(jù)轉(zhuǎn)換

  1. 封裝請求響應(yīng)類 ResponseResult
  2. 傳入 T 泛型碟案,數(shù)據(jù)轉(zhuǎn)換對應(yīng)類型,返回前臺
ResponseResult.ets 請求響應(yīng)封裝

export default class ResponseResult<T> {  
  code: string  
  msg: string | Resource  
  data?: T  
  constructor() {  
    this.code = ''  
    this.msg = ''  
  }  
}

NetWorkManage.ets  請求工具類
request<T>() {  
  // http.HttpRequestOptions 處理
  ...
  // http request url  
  let url = this.requestOption.path  
  if (!startsWithHttpOrHttps(this.requestOption.path)) {  
    url = this.BASE_URL + url  
  }  
  // execute interceptor  
  this.REQUEST_INTERCEPTORS.forEach((interceptor: HttpInterceptor) => {  
    interceptor.intercept(requestOption)  
  })  
  let httpRequest = http.createHttp();  
  
  // return result  
  let serverData: ResponseResult<T> = new ResponseResult()  
  return new Promise<ResponseResult<T>>((resolve, reject) => {  
    httpRequest.request(url, requestOption).then((value: http.HttpResponse) => {  
      // 轉(zhuǎn)換數(shù)據(jù)颇蜡,示例是json數(shù)據(jù)价说,如果是xml等需要自行處理
      let result: ResponseResult<T> = JSON.parse(`${value.result}`) as ResponseResult<T>  
      if (value.responseCode === http.ResponseCode.OK && result.code == 'success') {  
        serverData = result  
        resolve(serverData)  
      } else {  
        serverData.msg = `${$r('app.string.http_error_message')}&${value.responseCode}`  
        reject(serverData)  
      }  
  
    })  
      .catch(() => {  
        serverData.msg = $r('app.string.http_error_message')  
        reject(serverData)  
      })  
  })  
}

五辆亏、接口請求示例

在請求過程中,除了攔截器統(tǒng)一處理請求內(nèi)容熔任,也支持單個接口對 header 信息進(jìn)行定制處理
注意:請求 data 可以傳入 string褒链,也可以傳入 object,如果是 get 請求疑苔,官方庫會默認(rèn)轉(zhuǎn)把 object 類型換成 "key1=sss&uuu=222"甫匹,post 請求需要傳入 object

class NewsViewModel {  
  // 獲取新聞類型
  async getNewsTypeList(): Promise<NewsTypeModel[]> {  
    const result = await NetWorkManage.createRequest({  
      method: http.RequestMethod.GET,  
      path: Const.GET_NEWS_TYPE,  
      header: {  
        'test222': 'aqqq'  
      }  
    }).request<NewsTypeModel[]>()  
    if (result.code === 'success' && result.data) {  
      return result.data  
    }  
    return Const.TabBars_DEFAULT_NEWS_TYPES;  
  }  
  
  getDefaultNewsType(): NewsTypeModel[] {  
    return Const.TabBars_DEFAULT_NEWS_TYPES  
  }  

  // 獲取新聞列表
  getNewsList(currPage: number, pageSize: number, path: string): Promise<ResponseResult<NewsData[]>> {  
    const params: Record<string, number> = {  
      'currentPage': currPage,  
      'pageSize': pageSize  
    }  
    return NetWorkManage.createRequest({  
      method: http.RequestMethod.GET,  
      path: path,  
      data: params  
    }).request<NewsData[]>()  
  }  
}  
  
let newsViewModel = new NewsViewModel();  
  
export default newsViewModel as NewsViewModel;

服務(wù)端代碼

給一個服務(wù)端的簡易代碼,幫助開發(fā)者自行調(diào)試業(yè)務(wù)場景惦费,Python語言
https://gitee.com/Osbornjie/learn-align

pip install flask
pip install faker
python main.py // 啟動服務(wù)

總結(jié)

ScreenFlow.gif

上面的文章主要介紹了對 htpp 官方庫的封裝兵迅,不需要引入第三方請求庫,基本能滿足大多數(shù)應(yīng)用的開發(fā)薪贫,當(dāng)然也有設(shè)計不足的地方恍箭,比如 請求重試、請求隊(duì)列等瞧省,有時間再優(yōu)化

https://gitee.com/Osbornjie/net-util 這是本文源碼

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末扯夭,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子鞍匾,更是在濱河造成了極大的恐慌交洗,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,548評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件橡淑,死亡現(xiàn)場離奇詭異构拳,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)梁棠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評論 3 399
  • 文/潘曉璐 我一進(jìn)店門置森,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人符糊,你說我怎么就攤上這事凫海。” “怎么了男娄?”我有些...
    開封第一講書人閱讀 167,990評論 0 360
  • 文/不壞的土叔 我叫張陵盐碱,是天一觀的道長。 經(jīng)常有香客問我沪伙,道長瓮顽,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,618評論 1 296
  • 正文 為了忘掉前任围橡,我火速辦了婚禮暖混,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘翁授。我一直安慰自己拣播,他們只是感情好晾咪,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,618評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著贮配,像睡著了一般谍倦。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上泪勒,一...
    開封第一講書人閱讀 52,246評論 1 308
  • 那天昼蛀,我揣著相機(jī)與錄音,去河邊找鬼圆存。 笑死叼旋,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的沦辙。 我是一名探鬼主播夫植,決...
    沈念sama閱讀 40,819評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼油讯!你這毒婦竟也來了详民?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,725評論 0 276
  • 序言:老撾萬榮一對情侶失蹤陌兑,失蹤者是張志新(化名)和其女友劉穎沈跨,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體诀紊,經(jīng)...
    沈念sama閱讀 46,268評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,356評論 3 340
  • 正文 我和宋清朗相戀三年隅俘,在試婚紗的時候發(fā)現(xiàn)自己被綠了邻奠。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,488評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡为居,死狀恐怖碌宴,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蒙畴,我是刑警寧澤贰镣,帶...
    沈念sama閱讀 36,181評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站膳凝,受9級特大地震影響碑隆,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蹬音,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,862評論 3 333
  • 文/蒙蒙 一上煤、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧著淆,春花似錦劫狠、人聲如沸拴疤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,331評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽呐矾。三九已至,卻和暖如春懦砂,著一層夾襖步出監(jiān)牢的瞬間蜒犯,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,445評論 1 272
  • 我被黑心中介騙來泰國打工孕惜, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留愧薛,地道東北人。 一個月前我還...
    沈念sama閱讀 48,897評論 3 376
  • 正文 我出身青樓衫画,卻偏偏與公主長得像毫炉,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子削罩,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,500評論 2 359

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