前言
基于http封裝的一個網絡庫,里面有一個知識點,在初始化的時候,可以設置請求頭攔截和請求錯誤后的信息的攔截,具體案例如下:
et.getInstance().init({netErrorInterceptor: new MyNetErrorInterceptor(), //設置全局錯誤攔截,需要自行創建,可在這里進行錯誤處理netHeaderInterceptor: new MyNetHeaderInterceptor(), //設置全局頭攔截器,需要自行創建})
當請求發生錯誤時,就會把錯誤信息回傳至自定義的netErrorInterceptor里,同樣的,當發起一次請求時,如果有請求頭攔截,會先執行netHeaderInterceptor,把頭參數傳遞,再執行request,請求模式如下:
我們需要知道的是,在鴻蒙開發中,不像Android中的okhttp,為我們提供了一定的攔截器,鴻蒙中的http這個系統的Api沒有提供任何的攔截器概念的,這就導致了,我們如果想要實現統一的請求頭攔截,或者統一的錯誤處理,就需要自己定義了。
如何實現呢,和上述中的流程圖一樣,進行回調處理。
初始化傳入
我們可以通過全局初始化,進行設置對應的攔截,當然了不限于這兩種攔截,MyNetErrorInterceptor是自定義的錯誤攔截對象,需要繼承NetErrorInterceptor,MyNetHeaderInterceptor是自定義的請求頭攔截器對象,繼承于NetHeaderInterceptor。
Net.getInstance().init({netErrorInterceptor: new MyNetErrorInterceptor(), //設置全局錯誤攔截,需要自行創建,可在這里進行錯誤處理netHeaderInterceptor: new MyNetHeaderInterceptor(), //設置全局頭攔截器,需要自行創建})
需要注意的是,在同模塊下,我們可以使用接口創建我們的攔截對象,如果你想要打har包,或者不同的模塊,使用接口導出export是有問題的,如何解決呢,使用抽象類作為攔截對象,代碼如下:
MyNetErrorInterceptor繼承的NetErrorInterceptor對象:
import { NetError } from '../error/NetError';/*** AUTHOR:AbnerMing* DATE:2023/9/12* INTRODUCE:全局異常攔截* */
export abstract class NetErrorInterceptor {abstract httpError(error: NetError)
}
MyNetHeaderInterceptor繼承的NetHeaderInterceptor對象:
import { HttpHeaderOptions } from '../model/HttpHeaderOptions';/*** AUTHOR:AbnerMing* DATE:2023/9/13* INTRODUCE:全局頭參數攔截* */export abstract class NetHeaderInterceptor {abstract getHeader(options: HttpHeaderOptions): Promise<Object>
}
工具類接收
全局初始化設置以后,那么在Net工具類中,我們就需要接收了,接收賦值給成員變量之后,再通過方法進行暴露,方便后續的調用。
private mNetErrorInterceptor: NetErrorInterceptor //全局錯誤攔截
private mNetHeaderInterceptor: NetHeaderInterceptor //全局頭攔截器/** Author:AbnerMing* Describe:初始化*/init(options: NetOptions) {this.mNetErrorInterceptor = options.netErrorInterceptorthis.mNetHeaderInterceptor = options.netHeaderInterceptor}/** Author:AbnerMing* Describe:獲取全局錯誤攔截*/getNetError(): NetErrorInterceptor {return this.mNetErrorInterceptor}/** Author:AbnerMing* Describe:獲取全局頭攔截器*/getNetHeaderInterceptor(): NetHeaderInterceptor {return this.mNetHeaderInterceptor}
進行使用
前兩步,把動作已經實現,如何觸發這個動作,那么就需要調用了,也就是進行實現方法的調用,進行數據的回調,通過getNetError或者getNetHeaderInterceptor,拿到設置的對象,進行非空判斷之后,調用對象里的函數即可。
1、請求頭攔截調用
注意:這個攔截是在發起請求request之前進行設置,如果攔截,必須等待頭參數執行完畢。
if (Net.getInstance().getNetHeaderInterceptor() != null) {//需要攔截頭參數了Net.getInstance().getNetHeaderInterceptor().getHeader({url: this.getUrl(),method: this.getMethod(),params: this.getParams(),header: this.getHeaders()}).then((header) => {//發起請求this.setHeaders(header)this.doRequest(httpRequest,success, error,isReturnString, isReturnData)}).catch(() => {//發起請求this.doRequest(httpRequest,success, error,isReturnString, isReturnData)})}
2、錯誤攔截調用
當請求發生錯誤進行回調。
//全局回調錯誤信息if (Net.getInstance().getNetError() != null) {Net.getInstance().getNetError().httpError(new NetError(err.code, NetError.responseError(err.code)))}
信息回傳
如何拿到回傳數據?在第一步中的初始化設置中我們已經傳入了,在實現方法里獲取即可。
1、請求頭攔截對象
import { HttpHeaderOptions, NetHeaderInterceptor } from '@app/net'class MyNetHeaderInterceptor implements NetHeaderInterceptor {getHeader(options: HttpHeaderOptions): Promise<Object> {//進行簽名加密,設置請求頭等操作return null}
}
2、請求錯誤攔截對象
import { NetError } from '@app/net/src/main/ets/error/NetError';
import { INetErrorInterceptor } from '@app/net/src/main/ets/interceptor/INetErrorInterceptor';export class MyNetErrorInterceptor implements INetErrorInterceptor {httpError(error: NetError) {//這里進行攔截錯誤信息}
}
相關總結
有的老鐵可能會發出靈魂的拷問,為什么要在請求前進行回調,http不是提供了訂閱Header?事件嗎,可以在這里進行回調啊,確實,在發起請求之前,可以通過如下的代碼進行請求頭參數的訂閱,拿到請求頭參數的一些信息,同樣的也可以進行請求頭回調,也就是攔截。
httpRequest.on('headerReceive', (err, data) => {if (!err) {console.info('header: ' + JSON.stringify(data));} else {console.info('error:' + JSON.stringify(err));}
});
但是,有一種情況例外,那就是,如果你的請求頭回調對象里,有耗時操作,比如簽名加密等等,此時在訂閱里進行回調,會發生,已經發起請求了,但是請求頭參數未添加的情況,也就是請求不同步問題,所以,這種情況下,必須要等到請求頭參數執行完畢后再發起請求,就不能再訂閱里進行設置。