Retrofit结合OkHttp拦截器如何获取并打印接口注解路径
实现方案
Retrofit 2.5.0及以上版本在构建请求时,会自动将接口方法的调用元信息封装为retrofit2.Invocation对象,作为OkHttp Request的tag携带,无需额外配置即可在拦截器中读取,从中就能提取到接口注解上声明的原始路径模板。
完整拦截器代码
import okhttp3.Interceptor import okhttp3.Response import retrofit2.DELETE import retrofit2.GET import retrofit2.HEAD import retrofit2.HTTP import retrofit2.Invocation import retrofit2.OPTIONS import retrofit2.PATCH import retrofit2.POST import retrofit2.PUT import java.io.IOException class MyInterceptor : Interceptor { @Throws(IOException::class) override fun intercept(chain: Interceptor.Chain): Response { val request = chain.request() // 获取Retrofit自动附加的调用元信息 val invocation = request.tag(Invocation::class.java) if (invocation != null) { val apiMethod = invocation.method() // 从方法的HTTP注解中提取原始声明路径 val annotationPath = apiMethod.annotations.firstNotNullOfOrNull { ann -> when (ann) { is GET -> ann.value is POST -> ann.value is PUT -> ann.value is DELETE -> ann.value is PATCH -> ann.value is OPTIONS -> ann.value is HEAD -> ann.value is HTTP -> ann.path else -> null } } // 替换为项目实际使用的日志打印方式即可 println("接口注解声明路径:$annotationPath") } return chain.proceed(request) } }
注意事项
- 该方案依赖Retrofit 2.5.0及以上版本,低版本没有自动注入
Invocationtag的能力 - 如果接口方法使用
@Url注解动态指定全量请求地址,提取到的路径为空字符串,属于正常情况 - 除了路径模板,你还可以从
Invocation对象中获取调用时传入的实际参数、接口Class对象等信息,可按需扩展日志内容
将该拦截器添加到OkHttp Client中后,调用示例中的getPost方法时,就会稳定打印出注解声明的posts/{post_id}路径,不会被实际传入的参数值替换。
内容的提问来源于stack exchange,提问作者Ilya Gazman
相关产品推荐
相关产品推荐

