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

如何通过Interceptor修改Retrofit请求中@Query注解的参数

实现方案

通过自定义OkHttp拦截器统一修改请求参数即可实现需求,无需调整原有Retrofit接口定义,具体实现步骤如下:

步骤1:自定义本地化参数拦截器

继承Interceptor接口,在请求发出前统一添加/覆盖units和lang参数:

import okhttp3.Interceptor
import okhttp3.Response
import java.util.Locale

class LocalizationParamInterceptor : Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        val originalRequest = chain.request()
        val originalUrl = originalRequest.url

        // 生成本地化参数:可根据业务需求调整适配逻辑
        val currentLang = Locale.getDefault().language // 系统当前语言,如zh、en、ja等
        val currentUnit = when (Locale.getDefault().country) {
            // 美国、利比里亚、缅甸使用英制单位,其余地区默认使用公制单位
            "US", "LR", "MM" -> "imperial"
            else -> "metric"
        }

        // 构建新的请求URL,setQueryParameter会自动覆盖已存在的同名参数
        val newUrl = originalUrl.newBuilder()
            .setQueryParameter("units", currentUnit)
            .setQueryParameter("lang", currentLang)
            .build()

        // 生成新请求并放行
        val newRequest = originalRequest.newBuilder()
            .url(newUrl)
            .build()

        return chain.proceed(newRequest)
    }
}

注意:如果需要保留接口手动传入的参数优先级(即接口传了参数就用传入值,没传才用全局本地化值),可将setQueryParameter替换为如下逻辑:

val newUrlBuilder = originalUrl.newBuilder()
if (originalUrl.queryParameter("units") == null) {
    newUrlBuilder.addQueryParameter("units", currentUnit)
}
if (originalUrl.queryParameter("lang") == null) {
    newUrlBuilder.addQueryParameter("lang", currentLang)
}
val newUrl = newUrlBuilder.build()

步骤2:将拦截器添加到OkHttpClient配置中

修改原有OkHttpClient初始化代码,将自定义拦截器添加到拦截器链最前端:

val client = OkHttpClient.Builder().apply {
    // 先添加自定义参数拦截器,保证后续日志拦截器能打印到修改后的参数
    addInterceptor(LocalizationParamInterceptor())
    if (BuildConfig.DEBUG) {
        addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
    }
}.build()
val json = Json { ignoreUnknownKeys = true }
Retrofit.Builder()
    .baseUrl(BASE_URL)
    .client(client)
    .addConverterFactory(json.asConverterFactory(CONTENT_TYPE.toMediaType()))
    .build()

可选优化:仅针对天气接口修改参数

如果不希望全局所有请求都添加这两个参数,可在拦截器中增加路径判断,仅处理天气接口:

override fun intercept(chain: Interceptor.Chain): Response {
    val originalRequest = chain.request()
    // 仅匹配天气接口修改参数
    if (originalRequest.url.encodedPath.endsWith("weather")) {
        // 上述参数修改逻辑放在此处
    }
    // 其余请求直接放行
    return chain.proceed(originalRequest)
}

内容的提问来源于stack exchange,提问作者SoulReaver313

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 07:51:01