一般来说,一个APP中的域名应该固定只有一个。我们在网络请求时可以很方便的写上我们的域名来替代ip+端口号从而进行网络请求。但是有时候我们的应用需要,动态的设置我们的域名的时,写上固定的域名就无法使用了。关键是,在我们使用retrofit时,这种情况就更加的棘手。因为retrofit是默认不支持切换baseurl的。那么此时,我们可以通过本文的方法来进行baseurl的切换。
主要的思路是,在网络请求发出时,我们在okhttp中进行拦截,并对其进行修改。也就是说,我们通过retrofit发出的请求可能是错误的,因为域名是错的。但是我们拦截后进行了修改,把它变成正确的。
废话少说,上代码:
//拦截器
public class BaseUrlManagerInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
//获取原始的originalRequest
Request originalRequest = chain.request();
//获取当前的url
HttpUrl oldUrl = originalRequest.url();
Log.e("aaa", "intercept:------------oldUrl---------->" + oldUrl);
//获取originalRequest的创建者builder
Request.Builder builder = originalRequest.newBuilder();
//获取头信息的集合如:jeapp ,njeapp ,mall
List<String> urlnameList = originalRequest.headers("urlname");
if (urlnameList != null && urlnameList.size() > 0) {
//删除原有配置中的值,就是namesAndValues集合里的值
builder.removeHeader("urlname");
//获取头信息中配置的value,如:manage或者mdffx
String urlname = urlnameList.get(0);
Log.e("aaa", "intercept:-------urlname------ " + urlname);
HttpUrl baseURL = null;
//根据头信息中配置的value,来匹配新的base_url地址
if (!TextUtils.isEmpty(urlname)) {
switch (urlname) {
case ConstantUtils.JEAPP:
baseURL = HttpUrl.parse(ConstantUtils.PRE_URL);
break;
case ConstantUtils.NJEAPP:
baseURL = HttpUrl.parse(ConstantUtils.PRE_NEW_URL);
break;
case ConstantUtils.MALL:
baseURL = HttpUrl.parse(ConstantUtils.MALL_URL);
break;
default:
break;
}
/* if ("jeapp".equals(urlname)) {
baseURL = HttpUrl.parse(ConstantUtils.PRE_URL);
} else if ("njeapp".equals(urlname)) {
baseURL = HttpUrl.parse(ConstantUtils.PRE_NEW_URL);
} else if ("mall".equals(urlname)) {
baseURL = HttpUrl.parse(ConstantUtils.MALL_URL);
}*/
//重建新的HttpUrl,需要重新设置的url部分
HttpUrl newHttpUrl = oldUrl.newBuilder()
.scheme(baseURL.scheme())//http协议如:http或者https
.host(baseURL.host())//主机地址
.port(baseURL.port())//端口
.build();
Log.e("aaa", "intercept:------scheme---- " + baseURL.scheme());
Log.e("aaa", "intercept:-----host-----" + baseURL.host());
Log.e("aaa", "intercept:-----port----- " + baseURL.port());
//获取处理后的新newRequest
Request newRequest = builder.url(newHttpUrl).build();
return chain.proceed(newRequest);
}
return chain.proceed(originalRequest);
} else {
return chain.proceed(originalRequest);
}
}
}
我们在okhttp的配置中,添加该拦截器,代码如下:
OkHttpClient.Builder mBuilder = new OkHttpClient.Builder();
//替换baseUrl
mBuilder.addInterceptor(new BaseUrlManagerInterceptor());
此时,我们要做的只剩下在我们定义的接口api中把我们要访问的接口名称上,添加一个自己用来区分baseurl的请求头。代码如下:
@Headers({ConstantUtils.MALL_HEADERS})
@GET("api/app/*****")
Call<String> MallGetCateList();
到此整个替换方法结束。你可以写两个请求,调用两个域名不同接口进行测试~