Android对Retrofit的BaseUrl的适配
一个项目中,可能会遇到调用不同域名或者端口的接口,可是Retrofit对BaseUrl的设置方法并没有提供对不同域名的适配,我们的网络调用一般都是单例,那么不可能为每一个域名都建立一个实例,那样就失去了网络框架的意义,那么可以使用一下的方法来实现。
Headers
使用Headers请求的特性,里面的键值可以为我们区别请求的调用目的
@Headers({"url_type:weather"}) //url_type用来区别调用接口的标志()
@GET("api/index/weather")
Flowable<BaseBean<WeatherBean>> getweather(@Query("city") String city);
BaseUrl
public class ApiUrl {
//注意这里的接口的路径都只能到端口,不要加子集路径了
public static String BASEURL_WEATHER="http://api.xq.cspugoing.com/";
public static String BASEURL_LAUNCHER="http://192.168.10.128:8080/";
public static String HEADER_KEY="url_type";
}
Interceptor
//增加头部信息
Interceptor headerInterceptor =new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
String tokens= BaseSharePreference.getStringMes(BaseSharePreference.PERSONAL_LOGIN_TOKEN);
//获取request
Request request = chain.request();
//从request中获取原有的HttpUrl实例oldHttpUrl
HttpUrl oldHttpUrl = request.url();
//获取request的创建者builder
Request.Builder builder = request.newBuilder()
.addHeader("Content-Type", "application/json")
.addHeader("customer.token",tokens==null?"":tokens);
//从request中获取headers,通过给定的键url_type
List<String> headerValues = request.headers(ApiUrl.HEADER_KEY);
if (headerValues != null && headerValues.size() > 0) {
//如果有这个header,先将配置的header删除,因此header仅用作app和okhttp之间使用
builder.removeHeader(ApiUrl.HEADER_KEY);
//匹配获得新的BaseUrl
String headerValue = headerValues.get(0);
HttpUrl newBaseUrl = null;
if ("launcher".equals(headerValue)) {
newBaseUrl = HttpUrl.parse(ApiUrl.BASEURL_LAUNCHER);
}else if ("weather".equals(headerValue)) {
newBaseUrl = HttpUrl.parse(ApiUrl.BASEURL_WEATHER);
}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()
.readTimeout(READ_TIME_OUT, TimeUnit.SECONDS)
.connectTimeout(CONNECT_TIME_OUT, TimeUnit.SECONDS)
.writeTimeout(WRITE_TIME_OUT,TimeUnit.SECONDS)
.readTimeout(WRITE_TIME_OUT,TimeUnit.SECONDS)
.addInterceptor(mRewriteCacheControlInterceptor)
.addNetworkInterceptor(mRewriteCacheControlInterceptor)
.addInterceptor(headerInterceptor) //如此
.cache(cache)
.build();
即可实现单一的网络接口适配
路还很长,慢慢走