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

Retrofit 不使用Call时如何将参数作为请求Tag值传递给拦截器

解决方案

错误原因

你自定义的@Tagz注解不属于Retrofit内置支持的参数注解,因此Retrofit在解析接口方法时会认为该参数没有配置合法注解,抛出No Retrofit annotation found异常。

实现方案

你不需要自定义CallAdapter,也不需要修改原有suspend函数的返回结构,直接利用Retrofit内置的Invocation特性即可实现参数级动态Tag传递,步骤如下:

步骤1:保留自定义Tag注解

@Target(AnnotationTarget.VALUE_PARAMETER)
@Retention(AnnotationRetention.RUNTIME)
annotation class Tagz

步骤2:定义接口方法

和你原有写法保持一致即可:

@GET
suspend fun getUsers(@Tagz value: CachePolicy.Type, @Url placeholder: String): Response<UserEntity?>

步骤3:在拦截器中读取Tag值

Retrofit所有请求默认会携带Invocation类型的Tag,其中包含了当前请求对应的方法信息、参数注解、参数实际传入值,直接解析即可:

class CustomTagInterceptor : Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        val originRequest = chain.request()
        // 读取Retrofit自动注入的Invocation信息
        val invocation = originRequest.tag(Invocation::class.java) 
            ?: return chain.proceed(originRequest)
        
        // 遍历所有参数找到标注@Tagz的参数
        invocation.method().parameterAnnotations.forEachIndexed { index, annotations ->
            val tagzAnnotation = annotations.filterIsInstance<Tagz>().firstOrNull()
            if (tagzAnnotation != null) {
                // 拿到传入的Tag实际值
                val cachePolicy = invocation.arguments()[index] as? CachePolicy.Type
                // 按需处理,比如将值重新写入Request Tag方便后续其他拦截器使用
                val newRequest = originRequest.newBuilder()
                    .tag(CachePolicy.Type::class.java, cachePolicy)
                    .build()
                return chain.proceed(newRequest)
            }
        }

        return chain.proceed(originRequest)
    }
}

步骤4:注册拦截器

将上述拦截器添加到OkHttpClient的拦截器列表中即可生效。

注意事项

  • 该方案依赖Retrofit 2.6.0及以上版本,这是Retrofit支持suspend函数、默认注入Invocation Tag的最低版本要求
  • 如果需要传递多个不同类型的Tag,可给@Tagz添加key字段用于区分不同参数

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 03:51:00