如何在运行时更改含或不含路径段的Retrofit Base URL?
如何用Interceptor修改带路径段的Retrofit Base URL
要实现运行时替换包含路径段的Base URL(比如https://myapi.com/blog/v1或https://myapi.com/internal/blog/v1),并保证接口定义的路径(如posts/recent)能正确拼接,你可以通过自定义OkHttp Interceptor重新构建请求URL来实现,具体步骤如下:
1. 定义Base URL配置工具
先做一个全局的配置类,用来存储和切换当前的Base URL:
object ApiConfig { // 默认初始Base URL,后续可动态修改 var currentBaseUrl: String? = "https://myapi.com/blog/v1" }
2. 实现自定义Base URL拦截器
核心逻辑是拦截原始请求,用新的带路径的Base URL替换原Base URL,并拼接原始请求的路径、查询参数等部分:
class DynamicBaseUrlInterceptor : Interceptor { override fun intercept(chain: Interceptor.Chain): Response { val originalRequest = chain.request() val originalUrl = originalRequest.url // 获取当前配置的新Base URL,若为空则直接执行原请求 val newBaseUrlStr = ApiConfig.currentBaseUrl ?: return chain.proceed(originalRequest) val newBaseUrl = newBaseUrlStr.toHttpUrlOrNull() ?: return chain.proceed(originalRequest) // 构建新URL:新Base URL + 原始请求的路径段(过滤空段避免双斜杠) + 查询参数 val newUrl = newBaseUrl.newBuilder().apply { // 处理原始请求的路径段,跳过空值(比如接口用绝对路径@GET("/xxx")时的空首段) originalUrl.pathSegments.filterNot { it.isEmpty() }.forEach { addPathSegment(it) } // 保留原始请求的所有查询参数 originalUrl.queryParameterNames.forEach { key -> originalUrl.queryParameter(key)?.let { addQueryParameter(key, it) } } }.build() // 替换请求URL并执行 val modifiedRequest = originalRequest.newBuilder() .url(newUrl) .build() return chain.proceed(modifiedRequest) } }
3. 配置Retrofit时添加拦截器
初始化Retrofit时,将这个拦截器添加到OkHttpClient中:
val okHttpClient = OkHttpClient.Builder() .addInterceptor(DynamicBaseUrlInterceptor()) .build() val retrofit = Retrofit.Builder() .baseUrl("https://placeholder.com/") // 这里随便填一个合法URL即可,拦截器会替换 .client(okHttpClient) .addConverterFactory(GsonConverterFactory.create()) .build()
关键注意事项
- 路径拼接自动处理:OkHttp的
HttpUrl会自动处理斜杠问题,无论新Base URL末尾是否带斜杠,都不会出现重复斜杠的情况。 - 绝对路径接口兼容:如果接口定义用了绝对路径(如
@GET("/posts/recent")),拦截器中过滤空路径段的逻辑会自动跳过空值,避免生成https://myapi.com/blog/v1//posts/recent这种错误URL。 - 动态切换示例:需要切换Base URL时,直接修改
ApiConfig.currentBaseUrl即可,比如:ApiConfig.currentBaseUrl = "https://myapi.com/internal/blog/v1"
内容的提问来源于stack exchange,提问作者Augusto Carmo
相关产品推荐
相关产品推荐

