Retrofit存在多个BaseUrl,提供一种比较简单的方案

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013762572/article/details/88910098

来源

这原本来自一个比较蛋疼的请求,项目中本来是一个BaseURL的天下,这几天突然要调用第三方的身份证调用接口,与现在的URL地址不一致,本想Copy一个Retrofit配置完事,但是马丹周五又来了一个第三方的查询接口,真是日了狗.(项目本是政府项目,存在很多规划问题),不能又拷一个配置吧,算了,就思考怎么写一个吧。

又加上在复习Retrofit的源码,发现存在一个比较简单的解决方案,就是在使用OkHttpClient发送请求的时候,使用反射直接替换掉BaseURL即可。上代码:

我们一般存在这样的两个接口:

public interface GithubService {
	
	// 这是请求github的地址
    @GET("users/{user}/repos")
    Call<List<Repo>> listRepos(@Path("user") String user);
	
	// 这是请求gank.io的地址
    @GET("history/content/{month}/{day}")
    Call<GankEntity> getGankEntity(@Header(HXConstant.NEW_URL_KEY) String url,
                                   @Path("month") String month,
                                   @Path("day") String day);

}

其中HXConstant为:

public class HXConstant {
    public static final String NEW_URL_KEY = "new_url_key";
}

那么在发送请求时,需要重新写个我们自己的okhttp3.Call.Factory ,代码如下:

public class HxCallFactory implements okhttp3.Call.Factory {
	
	//真实请求还是OkHttpClient,只是在请求之前,换掉URL即可
    private okhttp3.Call.Factory realCall = new OkHttpClient();
    private String replaceURL;

    public HxCallFactory(String replaceURL) {
        this.replaceURL = replaceURL;
    }

    @Override
    public Call newCall(Request request) {
        Headers headers = request.headers();
        int headersSize = headers.size();

        if (headersSize > 0) {
         	//获取我所填的新的URL地址
            String newUrl = headers.get(HXConstant.NEW_URL_KEY);

            if (!TextUtils.isEmpty(newUrl)) { //获取新的url
                //旧的URL替换掉新的URL
                String newUrlStr = request.url().toString().replace(replaceURL, newUrl);
                HttpUrl newHttpUrl = HttpUrl.get(newUrlStr);

                //将header无用数据清除
                Headers createNewHeaders = createNewHeader(request.headers());

                Field urlField;
                Field headerField;
                try {
                    urlField = request.getClass().getDeclaredField("url");
                    urlField.setAccessible(true);
                    urlField.set(request, newHttpUrl);

                    headerField = request.getClass().getDeclaredField("headers");
                    headerField.setAccessible(true);
                    headerField.set(request,createNewHeaders);

                } catch (NoSuchFieldException | IllegalAccessException e) {
                    e.printStackTrace();
                }

                Log.d("URL2", "newCall: " + request.url());
            }
        }

        return realCall.newCall(request);
    }

	//刚才自己的对应的URL地址清除掉
    private Headers createNewHeader(Headers headers) {
        if (null == headers) return null;
        int headerSize = headers.size();

        okhttp3.Headers.Builder builder = new okhttp3.Headers.Builder();
        for (int i = 0; i < headerSize; i++) {
            if (HXConstant.NEW_URL_KEY.equals(headers.name(i))) continue;
            builder.add(headers.name(i), headers.value(i));
        }
        return builder.build();
    }
}

图上大致说明了思路,那么我们怎么用呢?

  1. 首先配置一下Retrofit:
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://api.github.com/")
                //直接添加这个HxCallFactory 即可
                //里面的参数是我们全局的BaseURL
                .callFactory(new HxCallFactory("https://api.github.com/"))
                .addConverterFactory(GsonConverterFactory.create())
                .build();
  1. BaseURL没有变化的请求:
        Call<List<Repo>> call = service.listRepos("Microhx");

        call.enqueue(new Callback<List<Repo>>() {
            @Override
            public void onResponse(Call<List<Repo>> call, Response<List<Repo>> response) {}

            @Override
            public void onFailure(Call<List<Repo>> call, Throwable t) {
                t.printStackTrace();
            }
        });
  1. 需要更换的URL,那么直接写入更换的URL即可:
//这里直接替换为新的请求数据 
//其他配置与原配置保持不变
Call<GankEntity> gankEntityCall =  service.getGankEntity("http://gank.io/api/","4","5");

gankEntityCall.enqueue(new Callback<GankEntity>() {
            @Override
            public void onResponse(Call<GankEntity> call, Response<GankEntity> response) {
                Log.i("TAG",String.valueOf(response.body()));
            }

            @Override
            public void onFailure(Call<GankEntity> call, Throwable t) {
                t.printStackTrace();
                Log.e("TAG","get error:" + t);
            }
        });

完工。

猜你喜欢

转载自blog.csdn.net/u013762572/article/details/88910098