如何通过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
相关产品推荐
相关产品推荐

