如何在Retrofit/OkHttp拦截器中仅当有值时添加pageToken参数
解决Retrofit动态添加非空查询参数问题(Blogger API分页场景)
问题根源
当pageToken为空字符串或null时,直接通过@Query传参(尤其是设空字符串默认值)会导致Retrofit将pageToken=或pageToken=null附加到请求URL中,而Blogger API不接受无效的空分页令牌,从而触发400 Bad Request错误。
最优解决方案:利用Retrofit自动忽略null查询参数特性
Retrofit默认会忽略值为null的@Query参数,只需调整接口定义和调用逻辑即可实现需求:
- 修改Retrofit接口定义
将pageToken参数设为可空类型,无需设置默认值:
@GET("posts") suspend fun getPostList(@Query("pageToken") pageToken: String?): Response<PostList>
*注意:如果你的BASE_URL是https://www.googleapis.com/blogger/v3/blogs/$BLOG_ID/posts/,可以将接口的@GET改为@GET("");更规范的做法是调整BASE_URL到博客根路径:
const val BASE_URL = "https://www.googleapis.com/blogger/v3/blogs/$BLOG_ID/"
这样接口用@GET("posts")更符合Retrofit的URL拼接规则。*
- ViewModel中简化调用逻辑
无需手动判断token是否为空,直接传入token.value即可(空值会被Retrofit自动忽略):
val response = mainRepository.remoteDataSource.getPostList(token.value)
验证效果
- 首次请求(
token.value为null):URL不会包含pageToken参数,请求格式为https://www.googleapis.com/blogger/v3/blogs/12345678910/posts?maxResults=20&key=API_KEY,符合要求。 - 分页请求(
token.value有效):URL自动附加&pageToken=ABCDE,正确触发分页查询。
为什么之前的尝试失败?
你之前给pageToken设置了空字符串默认值(pageToken: String=""),此时Retrofit会将pageToken=添加到URL中,而Blogger API会将空字符串判定为无效令牌,导致报错。改用可空类型后,null值会被Retrofit自动过滤,不会出现在请求参数里。
内容的提问来源于stack exchange,提问作者Dr Mido
相关产品推荐
相关产品推荐

