對Retrofit+Rxjava封裝的多BaseUrl適配

在這個項目中,我遇到了一個問題,當我使用之前封裝好的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的適配

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章