美文网首页程序员Android开发
Android OkHttp拦截器(修改url)

Android OkHttp拦截器(修改url)

作者: JingChen_ | 来源:发表于2020-11-03 18:22 被阅读0次

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

相关文章

网友评论

    本文标题:Android OkHttp拦截器(修改url)

    本文链接:https://www.haomeiwen.com/subject/pphivktx.html