利用 OkHttp Interceptor 模擬資料
客戶端開發過程中,偶爾我們會碰到服務端 API 尚未部署,而客戶端又需要資料除錯的情況。這時我們就可以根據與服務端協商定好的介面模擬資料的返回。
思路
主要思路是通過攔截網路請求,返回模擬資料。而根據所處的環境不同,攔截方式可分為兩種:
- 由接受網路請求的 PC 使用抓包工具進行攔截; 優點:不依賴客戶端平臺,無需變更客戶端程式碼
缺點:客戶端與攔截工具需處於同一網路環境下,一旦 PC 的 IP 發生變化,需要重新設定 - 客戶端自身產生網路請求時直接攔截。 優點:靈活、易於除錯 缺點:需要修改客戶端程式碼,不同平臺間可能各需修改一次
第一種方法主要是使用 Charles 等抓包工具進行攔截並偽造資料,網上教程較多,本文不再累述。第二種方法中,主要是利用 OkHttp 框架中的 Interceptor(OkHttp 中 Interceptor 分為 Application Interceptor 以及 Network Interceptor,本文中 Interceptor 均指 Application Interceptor。)對網路請求進行攔截,並返回模擬資料。
OkHttp Interceptor

在這裡插入圖片描述
如圖,OkHttp Interceptor 可以對 Request 和 Response 進行處理。
利用這一機制,我們可以對 Request 進行攔截並將模擬資料填充於 Response 中並返回上層,從而達到模擬資料的目的。
實現
FakeApiInterceptor.java
public class FakeApiInterceptor implements Interceptor { @Override public Response intercept(Chain chain) throws IOException { Response response; if (BuildConfig.DEBUG && chain.request().url().toString().equals(API_URL)) { String json = "{\"code\": 200, \"message\": \"success\"}"; response = new Response.Builder() .code(200) .addHeader("Content-Type", "application/json") .body(ResponseBody.create(MediaType.parse("application/json"), json)) .message(json) .request(chain.request()) .protocol(Protocol.HTTP_2) .build(); } else { response = chain.proceed(chain.request()); } return response; } }
Debug 版且 url 對應的 API 需要模擬服務端資料返回時對請求進行攔截處理,直接建立 Response 返回模擬資料。
配合 Retrofit 使用
搭配 Retrofit 時,需要先建立 OkHttpClient 並且呼叫 addInterceptor() 方法註冊 Interceptor。
OkHttpClient okHttpClient = new OkHttpClient().newBuilder() .addInterceptor(new FakeInterceptor()) .build(); Retrofit retrofit = new Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .client(okHttpClient) .build();
總結
利用 OkHttp Interceptor,我們只需在初始化 OkHttpClient 時新增一個提供模擬資料的 Interceptor 即可,而不需要改動網路請求的相關程式碼。當服務端 API 部署後,只需移除 .addInterceptor(new FakeInterceptor()) 就能正常訪問 API,相對比較靈活方便。
喜歡的話請幫忙轉發一下能讓更多有需要的人看到吧,有些技術上的問題大家可以多探討一下。

在這裡插入圖片描述

在這裡插入圖片描述
以上Android資料以及更多Android相關資料及面試經驗可在QQ群裡獲取:936903570。有加群的朋友請記得備註上簡書,謝謝。