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
相关产品推荐
相关产品推荐

