Retrofit 动态修改BaseUrl 操作

公众号:码农乐园 等级 750 0 0

开发中会遇到URL需要动态切换,若你还是通过gradle打包切换是否不太灵活,下面将介绍一下retrofit基于OKhttp中动态修改URL;

原理添加拦截器,在retrofit中的现实更加灵活了如下代码:


  private RetrofitUrlManager() {
        if (!DEPENDENCY_OKHTTP) { //使用本框架必须依赖 Okhttp
            throw new IllegalStateException("Must be dependency Okhttp");
        }
        UrlParser urlParser = new DefaultUrlParser();
        urlParser.init(this);
        setUrlParser(urlParser);
        this.mInterceptor = new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                if (!isRun()) // 可以在 App 运行时, 随时通过 setRun(false) 来结束本框架的运行
                    return chain.proceed(chain.request());
                return chain.proceed(processRequest(chain.request()));
            }
        };
    }

下面是对retrofit设置的URL解析及添加到拦截器中


 /**
     * 对 {@link Request} 进行一些必要的加工, 执行切换 BaseUrl 的相关逻辑
     *
     * @param request {@link Request}
     * @return {@link Request}
     */
    public Request processRequest(Request request) {
        if (request == null) return request;

        Request.Builder newBuilder = request.newBuilder();

        String url = request.url().toString();
        //如果 Url 地址中包含 IDENTIFICATION_IGNORE 标识符, 框架将不会对此 Url 进行任何切换 BaseUrl 的操作
        if (url.contains(IDENTIFICATION_IGNORE)) {
            return pruneIdentification(newBuilder, url);
        }

        String domainName = obtainDomainNameFromHeaders(request);

        HttpUrl httpUrl;

        Object[] listeners = listenersToArray();

        // 如果有 header,获取 header 中 domainName 所映射的 url,若没有,则检查全局的 BaseUrl,未找到则为null
        if (!TextUtils.isEmpty(domainName)) {
            notifyListener(request, domainName, listeners);
            httpUrl = fetchDomain(domainName);
            newBuilder.removeHeader(DOMAIN_NAME);
        } else {
            notifyListener(request, GLOBAL_DOMAIN_NAME, listeners);
            httpUrl = getGlobalDomain();
        }

        if (null != httpUrl) {
            HttpUrl newUrl = mUrlParser.parseUrl(httpUrl, request.url());
            if (debug)
                Log.d(RetrofitUrlManager.TAG, "The new url is { " + newUrl.toString() + " }, old url is { " + request.url().toString() + " }");

            if (listeners != null) {
                for (int i = 0; i < listeners.length; i++) {
                    ((onUrlChangeListener) listeners[i]).onUrlChanged(newUrl, request.url()); // 通知监听器此 Url 的 BaseUrl 已被切换
                }
            }

            return newBuilder
                    .url(newUrl)
                    .build();
        }

        return newBuilder.build();

    }

具体的使用,在retrofitAPI接口中添加@Headers({"Domain-Name: CONTROL"}) Domain-Name是key,CONTROL 设置的URL对应的key名称

  /**
 * -----------------------
 * @author: qiuxianfu
 * @date: 2021/1/27
 * -----------------------
 */
public interface PerformanceApi {
    @Headers({"Domain-Name: CONTROL"})
    @POST("xxx/xxx/getSiteAreaPlanning")
    Observable<PerformancesResponse> getDataList(@Query("userCode") String userCode);

    @Headers({"Domain-Name: CONTROL"})
    @POST("xxx/xxx/addDutyRoster")
    Observable<AddDutyTosterResponse> addDutyRoster(@Body AddDutyRosterRequest rosterRequest);

}

这里就是动态设置了,CONTROL这个和@Headers({"Domain-Name: CONTROL"}) 保持一致

RetrofitUrlManager.getInstance().putDomain("CONTROL", InfieldAppUtils.getServerControlHttp()); } 地址:https://github.com/qxf323/RetrofitUrlManager

收藏
评论区

相关推荐

Retrofit 支持suspend函数源码分析
Retrofit 2.6.0 之后支持接口suspend函数配合协程使用,举个例子: ApiService java interface LoginApiService : BaseService { @GET("/wxarticle/chapters/json") suspend fun getChapters(): BaseResp
项目实战之---AES 加密
ajax/index.js import axiosApi from '../js/fetch'; import { baseUrl, headerParams } from '../js/baseUrl'; // import引用AES源码js import CryptoJS from 'cryptojs/cryptojs'; console.lo
Retrofit 动态修改BaseUrl 操作
开发中会遇到URL需要动态切换,若你还是通过gradle打包切换是否不太灵活,下面将介绍一下retrofit基于OKhttp中动态修改URL; 原理添加拦截器,在retrofit中的现实更加灵活了如下代码: language private RetrofitUrlManager() { if (DEPENDENCY_OKHTT
死磕Java泛型(一篇就够)
Java泛型,算是一个比较容易产生误解的知识点,因为Java的泛型基于擦除实现,在使用Java泛型时,往往会受到泛型实现机制的限制,如果不能深入全面的掌握泛型知识,就不能较好的驾驭使用泛型,同时在阅读开源项目时也会处处碰壁,这一篇就带大家全面深入的死磕Java泛型。 泛型擦除初探相信泛型大家都使用过,所以一些基础的知识点就不废话了,以免显得啰嗦。
Retrofit封装Okhttp逻辑原理
总结自retrofit封装了Okhttp 本身并不能进行网络请求。只能在Android使用的网络请求框架。1.png2.pngrequest:统一完成(post/get/...) 回调陷阱:完成上一步网络请求才能进行下一步网络请求。3.pngRetrofit简化了网络请求。优化了网络请求的使用。4.png5.png7.pngbuild设计模式:参数》5个;
java常见的 http 请求库比较
java常见的http请求库有httpclient,RestTemplate,OKhttp,更高层次封装的 feign、retrofit ##1、HttpClient HttpClient:代码复杂,还得操心资源回收等。代码很复杂,冗余代码多,不建议直接使用。 ##2、RestTemplate RestTemplate: 是 Spring 提供的用于访问
URI URL java 输出
URI uri =new URI("http://myname@www.baidu.com:8888/path1/path1?query1=value1#fffffff"); System.out.println("URI.getAuthority() = "+uri.getAuthority()); System.ou
11.前台文件数据流下载获取源文件名
1.文件流下载文件 ========= axios实现: export function download(url, data){ axios.post(baseurl+url,data,{responseType: 'blob'}) .then(function (response) {
Android笔记之Retrofit与RxJava的组合
**依赖** implementation 'com.squareup.retrofit2:retrofit:2.5.0' implementation 'com.squareup.retrofit2:converter-gson:2.5.0' implementation 'com.squareup.retrofit2:adapt
CentOS yum安装Mysql5.7
Mysql5.7  ========= # cd /etc/yum.repos.d/ # 新增编辑一个yum源 # vim mysql.repo 内容:  [mysql57-community] name=MySQL 5.7 Community Server ## baseurl=http://
Nginx的安装
在一个新的 centOS7.5 的系统中安装 1. 安装 Nginx 在 /etc/yum.repos.d/  目录下新建一个文件 名为  nginx.repo   输入以下内容并保存 **\[nginx\]** **name=nginx repo** **baseurl=http://nginx.org/packages/centos/7/$
Retrofit2的GsonConverterFactory.create()和RxJava2CallAdapterFactory.create()的实现过程以及执行过程
**一概述**   上一节分析了retrofit2从创建到执行的完整流程,本节分析一下两个非常重要的功能。数据转换器的实现以及网络请求适配器的实现。 **二、GsonConvertFactory.create()数据转换器的实现过程以及执行过程**   我们先看下GsonConvertFactory.crete()的源代码,此类在retrofit-co
Retrofit源码解析(上)
简介 Retrofit是Square公司开发的一款针对Android网络请求的框架,官网地址http://square.github.io/retrofit/ ,在官网上有这样的一句话介绍retrofit,A type-safe HTTP client for Android and Java。我们知道Retrofit底层是基于OKHttp实现的。对ok
Retrofit网络框架入门使用
1.简单介绍 ====== retrofit事实上就是对okhttp做了进一步一层封装优化。 我们仅仅须要通过简单的配置就能使用retrofit来进行网络请求了。 Retrofit能够直接返回Bean对象,比如假设我们进行一个网络接口的请求。返回来一串json字符串。那么这个时候一般我们都要拿到这个json字符串后进行解析得到相应的Bean对象,Ret
Retrofit里面Gson解析日期出错
今天解析json数据的时候出错了。 Invalid time zone indicator '6' (at offset 0) 也配置了Gson的setDateFormat格式 ,然而并没有用 最后还是加了registerTypeAdapter,这下通用了 private static final Gson gson = new GsonBuild