You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在运行时更改含或不含路径段的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 19:10:01