Retrofit中使用多个baseUrl

在使用Retrofit之前需要进行Retrofit的创建,如下:

return Retrofit.Builder()
        .baseUrl(NetClient.getInstance().getNetConfig().baseUrl)
        .client(NetClient.getInstance().getHttpClient())
        .addConverterFactory(GsonConverterFactory.create())
        .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
        .build()

这个创建过程是通过Builder进行的,如果项目中需要使用多个baseUrl,就没办法使用类似setBaseUrl的方法进行修改

那你能帮帮我吗?

1.可以使用@url注解直接进行url的设置,不使用baseurl
缺点:繁琐
优点:直接
2.使用临时header在拦截器中拼接不同的url
优点:一次修改,方便扩展,方便使用

具体做法:
1.首先需要定义一个Map来保存和标记不同的baseurl,如:

private val url = hashMapOf(
   Pair("v", "https://x.xxxxxx.com")
   , Pair("wx", "https://wx.xxxxxxx.com")
   , Pair("im", "https://im.xxxxxx.com")
   , Pair("ws", "wss://xxxx.xxxx.com/ws")
)

而且可以定义多个map用来切换不同的网络环境

2.在retrofit的具体请求接口中使用header进行标记,如:

@Headers("url_name:v")//这个对应了上面map中的key,url_name是随便定义的,但是后面要用到 

3.在http拦截器中进行处理,具体的方法如下:

override fun intercept(chain: Interceptor.Chain): Response {
    //获取request
    val request = chain.request()
    //获取request的创建者builder
    val builder = request.newBuilder()
    //从request中获取headers,通过给定的键url_name
    val headerValues = request.headers("url_name")
 
    if (headerValues.size > 0) {
        //如果有这个header,先将配置的header删除,因此header仅用作app和okhttp之间使用
        builder.removeHeader(NetConfig.HEADER_KEY)
        //匹配获得新的BaseUrl
        val headerValue = headerValues[0]
        val newBaseUrl = getNewBaseUrl(headerValue)
        //从request中获取原有的HttpUrl实例oldHttpUrl
        val oldHttpUrl = request.url()
        //重建新的HttpUrl,修改需要修改的url部分
        var newFullUrl:HttpUrl? = null
        //如果定义的map中存在这个url,就构建新的url,否则直接进行请求
        if (newBaseUrl != null) {
            val urlBuilder = oldHttpUrl.newBuilder()//使用旧的url构建一个新的Builder
            newFullUrl = urlBuilder
                .scheme(newBaseUrl.scheme())
                .host(newBaseUrl.host())
                .port(newBaseUrl.port()).build()//修改url的协议,域名,端口为新的url,可以根据自己的需求修改其他部分比如path,params
            return chain.proceed(builder.url(newFullUrl!!).build())
        }else{
            chain.proceed(request)
        }
    }
}
 
//从定义好的map中获取对应的url
private fun getNewBaseUrl(headerValue: String): HttpUrl? {
    return if (NetConfig.urlMap[headerValue] != null) {
        HttpUrl.parse(NetConfig.urlMap[headerValue]!!)!!
    } else null
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。