Android OkHttp 拦截器(修改url)

code小生 一个专注大前端领域的技术平台公众号回复Android加入安卓技术群

作者:敬琛
链接:https://www.jianshu.com/p/aa7928d98116
声明:本文已获敬琛授权发表,转发等请联系原作者授权

最近在项目里遇到类似配置化域名的需求,分享和记录下是什么实现的。用过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有问题直接丢给后端去看了嘿嘿,或者有想到解决方案的同学可以在下面留言 :)

相关阅读

1
2
3
4
5

https://www.jianshu.com/p/e8b6cafa91d5


如果你有写博客的好习惯
欢迎投稿
赞+在看,小生感恩❤️
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值