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

Retrofit2+Kotlin开发时URL意外变更引发422错误的问题排查

问题原因与解决方案

嘿,这个问题我之前踩过坑!咱们先来拆解下原因,再给你两个靠谱的解决办法:

问题根源

Retrofit的@Query注解默认会自动对参数值做URL编码,这本来是个省心的设计——它会帮你把冒号、空格这类特殊字符转换成符合URL规范的编码(比如把:转成%3A)。但你传入的start和end已经是手动编码好的字符串(带着%3A),Retrofit看到%这个特殊字符,就会把它再次编码成%25,最终参数就变成了2019-08-08T02%253A17%253A59Z,服务器完全认不出这个格式,自然返回422错误啦。

解决方案

方案1:传入原始日期字符串(推荐)

直接给接口传未编码的原始日期,让Retrofit帮你做编码,这是最稳妥的方式,避免手动编码的失误。

修改请求调用代码:

val start = "2019-08-08T02:17:59Z" // 直接用冒号,不用手动转%3A
val end = "2019-09-01T00:00:00Z"
val response: Response<List<CurrencySparkline>> = api.getCurrenciesSparkline(start, end).execute()

Retrofit会自动把:转成%3A,最终生成的URL参数就是API要求的格式啦。

方案2:强制Retrofit不编码参数(仅当必须用已编码字符串时)

如果你因为某些原因必须传入已编码的字符串,可以给@Query注解加上encoded = true参数,告诉Retrofit直接使用你传入的字符串,不要再做编码处理。

修改接口定义:

interface CurrenciesApi {
    @GET("currencies/sparkline?key=${apiKey}")
    fun getCurrenciesSparkline(
        @Query("start", encoded = true) start: String,
        @Query("end", encoded = true) end: String
    ): Call<List<CurrencySparkline>>
}

这样你的%3A就不会被二次编码,参数会原封不动地拼到URL里。

小提示

优先选方案1哦!手动编码很容易出现疏漏,比如不小心漏编某个特殊字符,或者编码规则和服务器要求不匹配,让框架处理编码才是最佳实践~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:07:42