在這個項目中,我遇到了一個問題,當我使用之前封裝好的Retrofit+Rxjava代碼進行網絡請求,發現BaseUrl是固定在初始化處的,但是這次的Api,BaseUrl有多個,而我的Retrofit是單例模式,但是對每一個BaseUrl都建立一個實例顯然不是一個明智的措施。
那麼我先說說的我處理方法,給Api添加請求頭,再給OkHttp添加一個攔截器,在攔截器中檢測頭部信息的Type,通過區分Type的方式來設置BaseUrl,再把Headers刪除。
Headers
使用Headers請求的特性,裏面的鍵值可以爲我們區別請求的調用目的
@GET("weather/hourly?")
Observable<HeWeather> getWeatherHourly(@Query("location") String id, @Query("key") String key);
@Headers({"url_type:air"})
@GET("air/now?")
Observable<HeWeather> getAirNow(@Query("location") String id, @Query("key") String key);
BaseUrl
public class Constans{
public final static String businessBaseUrl="https://api.heweather.net/s6/";
public final static String freeBaseUrl= "https://free-api.heweather.net/s6/";
public static String HEADER_KEY="url_type";
}
Interceptor
Interceptor headerInterceptor =new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
//獲取request
Request request = chain.request();
//從request中獲取原有的HttpUrl實例oldHttpUrl
HttpUrl oldHttpUrl = request.url();
//獲取request的創建者builder
Request.Builder builder = request.newBuilder()
.addHeader("Content-Type", "application/json");
//從request中獲取headers,通過給定的鍵url_type
List<String> headerValues = request.headers(Constans.HEADER_KEY);
if (headerValues != null && headerValues.size() > 0) {
//如果有這個header,先將配置的header刪除,因此header僅用作app和okhttp之間使用
builder.removeHeader(Constans.HEADER_KEY);
//匹配獲得新的BaseUrl
String headerValue = headerValues.get(0);
HttpUrl newBaseUrl = null;
if ("air".equals(headerValue)) {
newBaseUrl = HttpUrl.parse(Constans.businessBaseUrl);
}else{
newBaseUrl = oldHttpUrl;
}
//重建新的HttpUrl,修改需要修改的url部分
HttpUrl newFullUrl = oldHttpUrl
.newBuilder()
.scheme(newBaseUrl.scheme())//更換網絡協議
.host(newBaseUrl.host())//更換主機名
.port(newBaseUrl.port())//更換端口
// .removePathSegment(0)//移除第一個參數
.build();
//重建這個request,通過builder.url(newFullUrl).build();
// 然後返回一個response至此結束脩改
return chain.proceed(builder.url(newFullUrl).build());
}
return chain.proceed(request);
}
};
然後將這個攔截放入你的okhttp的初始化中
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.addInterceptor(ApiInterceptor().headerInterceptor)
.build();
實現多個BaseUrl的適配