美文网首页
使用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