美文网首页
使用Interceptor解决Retrofit 多个BaseUr

使用Interceptor解决Retrofit 多个BaseUr

作者: 蜗牛加油 | 来源:发表于2019-05-06 12:15 被阅读0次

    在实际开发中经常会遇到多个BaseUrl的问题,一般的处理方式是创建多个retrofit实例,那有没有办法进行动态的切换BaseUrl ?能不能使用Interceptor来解决这个问题? 答案是可以的。

    看代码:

    **
     * change baseUrl by api header setting
     */
    public class MultiDomainInterceptor implemants Intercaptor {
        private static final String TAG = "MultiDomainInterceptor";
    
        @Override
        public Response intercept(Chain chain) throws IOException {
            if (isIntercept(chain)) {
                return chain.proceed(processRequest(chain.request()));
            }else {
                return chain.proceed(chain.request());
            }
        }
    
        /**
         * @param request {@link Request}
         * @return {@link Request}
         */
        public Request processRequest(@NonNull Request request) {
            if (request.headers(BASE_URL).size() > 0) {
                String baseUrl = getBaseUrlFromHeaders(request);
                LogUtil.d(TAG, request);
                if (!TextUtils.isEmpty(baseUrl)) {
                    Request.Builder requestBuilder = request.newBuilder();
                    requestBuilder.removeHeader(BASE_URL);
    
                    HttpUrl domainUrl = HttpUrl.parse(baseUrl);
                    HttpUrl.Builder builder = request.url().newBuilder();
                    HttpUrl parsedHttpUrl = builder
                            .scheme(domainUrl.scheme())
                            .host(domainUrl.host())
                            .port(domainUrl.port())
                            .build();
                    requestBuilder.url(parsedHttpUrl);
                    Request parsedRequest;
                    if (request.tag() != null) {
                        parsedRequest = requestBuilder.tag(null).build();
                    } else {
                        parsedRequest = requestBuilder.build();
                    }
                    return parsedRequest;
                }
            }
            return request;
        }
    
        /**
         * get BaseUrl from header
         *
         * @param request
         * @return
         */
        private String getBaseUrlFromHeaders(Request request) {
            List<String> headers = request.headers(BASE_URL);
            if (headers == null || headers.size() == 0)
                return null;
            if (headers.size() > 1)
                throw new IllegalArgumentException("Only one BaseUrl in the headers");
            return request.header(BASE_URL);
        }
    
        private boolean isIntercept(Chain chain) throws IOException{
            return true;
        }
    }
    

    这里核心的代码主要是在processRequest 里面,这里面主要处理的url, tag,header的处理,下面说一下url 和 tag的处理过程,header比较简单:

    url里面保存了request的地址信息, 而tag的处理可以看Request中的注释:

    /**
        * Attaches {@code tag} to the request. It can be used later to cancel the request. If the tag
        * is unspecified or null, the request is canceled by using the request itself as the tag.
        */
       public Builder tag(Object tag) {
         this.tag = tag;
         return this;
       }
    

    因此上面代码中将转换后的tag赋值为空, 这种设置可能有问题,但是验证时正常,有了解的朋友麻烦指正

    下面看一下处理前后的request对象的区别:

    处理前

    {
        "headers": {
            "namesAndValues": ["base_url", "http://localhost:8080"]
        },
        "method": "GET",
        "url": {
            "host": "xxxxxxxxx.com",
            "password": "",
            "pathSegments": ["person", "list"],
            "port": 80,
            "scheme": "http",
            "url": "http://xxxxxxxxx.com/person/list",
            "username": ""
        }
    }
    

    处理后

    {
        "headers": {
            "namesAndValues": []
        },
        "method": "GET",
        "url": {
            "host": "localhost:8080",
            "password": "",
            "pathSegments": ["person", "list"],
            "port": 8080,
            "scheme": "http",
            "url": "http://localhost:8080/person/list",
            "username": ""
        }
    }
    

    相关文章

      网友评论

          本文标题:使用Interceptor解决Retrofit 多个BaseUr

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