工作中记录一下Kotlin动态切换URL的这种需求
这里解决动态修改baseUrl的方法是:在设置请求头的拦截器里面,动态获取了接口地址,例如:http://127.0.0.1:8000,然后将该url进行字符串截取获取http协议,ip服务器地址,以及端口号。
获取请求的url然后将拿到的http协议,服务器地址和端口号进行重新设置并返回,达到动态修改baseUrl的目的
package com.smart.sanitation.net
import com.smart.sanitation.MainApplication
import com.smart.sanitation.config.globalData
import com.smart.sanitation.net.gson.MGson
import com.smart.sanitation.net.utils.LogUtils
import com.smart.sanitation.ui.home.common.DictionaryConstant
import okhttp3.*
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.util.concurrent.TimeUnit
var ip = ""
/**
* 接口请求工厂
*/
object ApiFactory {
// 日志拦截器
private val mLoggingInterceptor: Interceptor by lazy { LoggingInterceptor() }
// 请求头添加session
private val mHeadersInterceptor: Interceptor by lazy { HeadersInterceptor() }
// OkHttpClient客户端
private val mClient: OkHttpClient by lazy { newClient() }
/**
* 创建API Service接口实例
*/
fun <T> createService(baseUrl: String, clazz: Class<T>): T =
Retrofit.Builder()
.baseUrl(baseUrl)
.client(mClient)
.addConverterFactory(GsonConverterFactory.create(MGson.getInstance()))
.build().create(clazz)
/**
* OkHttpClient客户端
*/
private fun newClient(): OkHttpClient = OkHttpClient.Builder().apply {
connectTimeout(30, TimeUnit.SECONDS)// 连接时间:30s超时
readTimeout(30, TimeUnit.SECONDS)// 读取时间:10s超时
writeTimeout(30, TimeUnit.SECONDS)// 写入时间:10s超时
addInterceptor(mHeadersInterceptor)
if (MainApplication.isDebugMode) addInterceptor(mLoggingInterceptor)// 仅debug模式启用日志过滤器
}.build()
/**
* 设置请求头
*/
private class HeadersInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val original: Request = chain.request()
val requestBuilder: Request.Builder = original.newBuilder()
.addHeader("Authorization", globalData.token)
.addHeader("isToken", globalData.isToken.toString())
.addHeader("TENANT-ID", globalData.tenantId)
val request: Request = requestBuilder.build()
//这里if我是用于默认url不需要更改baseUrl的判断,不需要此业务可去除,不影响
if (DictionaryConstant.isLogin && ip != DictionaryConstant.selectIpServer) {
val lastIndexOf = DictionaryConstant.selectIpServer.lastIndexOf(":")
val indexOf = DictionaryConstant.selectIpServer.indexOf("://")
val http = DictionaryConstant.selectIpServer.substring(0, 4)
val ip = DictionaryConstant.selectIpServer.substring(indexOf + 3, lastIndexOf)
val port = DictionaryConstant.selectIpServer.substring(lastIndexOf + 1)
//重建新的HttpUrl,修改需要修改的url部分
val newHttpUrl = original.url
.newBuilder()
.scheme(http)//更换http协议如:http或者https
.host(ip)//更换主机地址
.port(port.toInt())//更换端口
.build()
DictionaryConstant.isLogin = false
//返回处理后的新newRequest
return chain.proceed(requestBuilder.url(newHttpUrl).build());
}
return chain.proceed(request)
}
}
/**
* 日志拦截器
*/
private class LoggingInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val builder = StringBuilder()
val startTime = System.nanoTime()
val response: Response = with(chain.request()) {
builder.append(method + "\n")
builder.append("Sending request\n$url")
if (method == "POST") {
builder.append("?")
when (val body = body) {
is FormBody -> {
for (j in 0 until body.size) {
builder.append(body.name(j) + "=" + body.value(j))
if (j != body.size - 1) {
builder.append("&")
}
}
}
is MultipartBody -> {}
}
}
builder.append("\n").append(headers)
LogUtils.v(builder.toString())
chain.proceed(this)
}
builder.clear()
builder.append("Received response in " + (System.nanoTime() - startTime) / 1e6 + "ms\n")
builder.append("code" + response.code + "\n")
LogUtils.v(builder.toString())
return response
}
}
}
这里关键性代码,核心代码只需要这一部分即可:
//重建新的HttpUrl,需要修改的url部分
val newHttpUrl = original.url
.newBuilder()
.scheme(http)//更换http协议如:http或者https
.host(ip)//更换主机地址
.port(port.toInt())//更换端口
.build()
DictionaryConstant.isLogin = false
//返回处理后的新newRequest
return chain.proceed(requestBuilder.url(newHttpUrl).build());
本文介绍了如何在Kotlin项目中使用Retrofit通过拦截器动态改变HTTP请求的baseUrl,通过截取并替换URL中的协议、服务器地址和端口号,实现实时配置。
&spm=1001.2101.3001.5002&articleId=125457222&d=1&t=3&u=a8a12c92b4664f0ab4ef6879c5129e86)
1309

被折叠的 条评论
为什么被折叠?



