一
最近在项目里遇到类似配置化域名的需求,分享和记录下是什么实现的。用过OKHttp的肯定对拦截器不陌生。Interceptor,我们可以自定义设置OKHttp的拦截器之一,每次网络请求它都只执行一次拦截,而且它是的第一个触发拦截的,如果想对拦截器进一步了解,可以搜索相关文章,本章只做url修改配置的操作。
二
先从简单的模式讲起,只修改域名的操作
String baseUrl = "http://www.baidu.com" //你要切换的域名
private final Interceptor reUrlInterceptor = chain -> {
Request request = chain.request();
Request.Builder builder = request.newBuilder();
HttpUrl oldHttpUrl = request.url(); //从request中获取原有的HttpUrl实例oldHttpUrl
HttpUrl newBaseUrl = HttpUrl.parse(baseUrl);
//重建新的HttpUrl,配置成我们需要的
HttpUrl newFullUrl = oldHttpUrl
.newBuilder()
.scheme(newBaseUrl.scheme())
.host(newBaseUrl.host()) //新的url的域名
.port(newBaseUrl.port())
.build();
return chain.proceed(builder.url(newFullUrl).build());
};
其中,scheme代表url中"http://"字段,host代表"www.baidu.com",port代表端口号,在原来url的基础上,只更改了scheme、端口号和域名,build完后生成新的HttpUrl,之后返回出去。这样你就得到你想设定或者配置的url了。
三
这次项目需求比较奇葩,不同域名下,接口前面字段不同,例如,A域名:http://AAAA.com,B域名:http://BBBB.com。A域名接口前面加A1字段,B域名后面加B1字段。相当于你在中间插入一个字段。要知道,HttpUrl中没有这样的方法,它只给出addPathSegment()在接口后面添加字段,还有setPathSegment()替换字段,而且这个替换是你原有接口字段排序替换,不好判断接口字段个数,例如:现有url = "http://AAAA.com/A/B/C",假如你执行setPathSegment("D")和setPathSegment("E"),之后你build出来的url是"http://AAAA.com/D/E/C"。
这次思路是这样的:我先把 域名 + 字段(接口前面的字段)拼接好,得到只有"http://AAAA.com/A1"类似的url,之后再用原有的url中接口字段遍历出来一个个补到刚才得到的url后面,再build出一个新的HttpUrl返回出去,这样的url就包含你想要添加接口前面的字段还有原来的接口字段。
String baseUrl = "http://www.baidu.com" //你要切换的域名
private final Interceptor reUrlInterceptor = chain -> {
Request request = chain.request();
Request.Builder builder = request.newBuilder();
HttpUrl oldHttpUrl = request.url(); //原来的URL "http://AAAA.com/B/C/D"
HttpUrl newBaseUrl;
newBaseUrl = HttpUrl.parse(baseUrl + "AAA"); // "http://www.baidu.com/AAA"
HttpUrl newFullUrl = newBaseUrl; //缺少接口字段
for (int i = 0; i <= oldHttpUrl.pathSegments().size() - 1; i++) { //循环add原先接口字段
newFullUrl = newFullUrl.newBuilder()
.addPathSegment(oldHttpUrl.pathSegments().get(i))
.build();
}
// "http://www.baidu.com/AAA/B/C/D"
return chain.proceed(builder.url(newFullUrl).build());
};
这样就拼接好了,理论上看起来没啥问题,但忽略了一个细节,假如接口请求是带有参数的GET方法,后面参数就不见了。我是这样解决的,在你得到原有的url中判断是否有"?",如果有,就从"?"处分割url,得到后半部分,在重建新的url后补上去,得到最终的url。
String baseUrl = "http://www.baidu.com" //你要切换的域名
private final Interceptor reUrlInterceptor = chain -> {
Request request = chain.request();
Request.Builder builder = request.newBuilder();
HttpUrl oldHttpUrl = request.url(); //原来的URL "http://AAAA.com/B/C/D?id=111&time=222"
HttpUrl newBaseUrl;
newBaseUrl = HttpUrl.parse(baseUrl + "AAA"); // "http://www.baidu.com/AAA"
String url1 = "";
if (oldHttpUrl.url().toString().contains("?")){
String[] url = oldHttpUrl.url().toString().split("\\?",2);
url1 = "?" + url[1]; //url1 = "?id=111&time=222"
}
HttpUrl newFullUrl = newBaseUrl; //缺少接口字段
for (int i = 0; i <= oldHttpUrl.pathSegments().size() - 1; i++) { //循环add原先接口字段
newFullUrl = newFullUrl.newBuilder()
.addPathSegment(oldHttpUrl.pathSegments().get(i))
.build();
} // "http://www.baidu.com/AAA/B/C/D"
if (!url1.isEmpty()){
newFullUrl = HttpUrl.parse(newFullUrl.url().toString() + url1);
}
//"http://www.baidu.com/AAA/B/C/D?id=111&time=222"
return chain.proceed(builder.url(newFullUrl).build());
};
实践后发现没什么大问题,现在还有个隐性问题是,假如取到后端返回的url是有问题的,这里还没去做处理,url有问题直接丢给后端去看了嘿嘿,或者有想到解决方案的同学可以在下面留言 :)
网友评论