如何使用 Kotlin Coroutines 在 Retrofit 中处理 204 响应?
Posted
技术标签:
【中文标题】如何使用 Kotlin Coroutines 在 Retrofit 中处理 204 响应?【英文标题】:How to handle 204 response in Retrofit using Kotlin Coroutines? 【发布时间】:2020-04-25 10:05:25 【问题描述】:我正在使用带有 Kotlin 协程的 Retrofit 2.7.1。
我有这样定义的改造服务:
@PUT("/users/userId.json")
suspend fun updateUserProfile(
@Path("userId") userId: String,
@Query("display_name") displayName: String) : Void
此调用返回 HTTP 204 No Content 响应,这会导致 Retrofit 崩溃:
kotlin.KotlinNullPointerException: Response from com.philsoft.test.api.UserApiService.updateUserProfile was null but response body type was declared as non-null
at retrofit2.KotlinExtensions$await$2$2.onResponse(KotlinExtensions.kt:43)
at retrofit2.OkHttpCall$1.onResponse(OkHttpCall.java:129)
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:174)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
如何在改造中使用协程处理 204 响应而不崩溃?
【问题讨论】:
可能在这里回答:***.com/questions/37116364/… 【参考方案1】:据此,在改造方法声明中使用Response<Unit>
。
retrofit no content issue
【讨论】:
我在这个问题上花了将近 2 天的时间,终于可以正常使用您的解决方案了。谢谢。【参考方案2】:您可以使用Response<Unit>
来处理使用Retrofit
的204 个响应,但是当您这样处理时,Retrofit
不会针对4xx
响应或其他异常情况抛出异常。
您可以使用以下代码处理这些情况:
return try
val result = apiCall.invoke()
return if (result is Response<*>)
if (result.code() >= 400)
// create an error from error body and return
else
// return success result
else
// directly return success result
catch (t: Throwable)
// create an error from throwable and return it!
【讨论】:
如何从205获取消息数据?【参考方案3】:用示例代码解释@Dmitri 的答案:
在您的 APIInterface 中,像这样调用您的 API,
@GET(AppConstants.APIEndPoints.GET_NEWS)
suspend fun getNews(
@Query("limit") limit: String,
): Response<NewsListResponseModel>
其中,响应是retrofit2.Response
从您调用 API 的位置,检查来自函数的状态代码,例如 apiResponse.code()
。
val apiResponse = apiEndPointsInterface.getNews(limit)
if (apiResponse.code() == HttpURLConnection.HTTP_OK)
//response success
ResultOf.Success(apiResponse.body()!!))
else
//handle your other response codes here
ResultOf.Failure("No Data Found.", null))
【讨论】:
最后它可以与您的解决方案一起正常工作。谢谢。【参考方案4】:这可能对某人有帮助 我添加了错误的标头,导致我出现 HTTP 400 Bad request 错误。
.addHeader("Content-Encoding", "UTF-8")
.header("Accept-Encoding", "identity")
【讨论】:
这是我遇到的一个案例,当时我添加了错误的标题,所以可能会帮助某人交叉检查。 @RichardBarber:甚至在编辑之前,它就提供了答案。 @JeremyCaney 回滚完成以上是关于如何使用 Kotlin Coroutines 在 Retrofit 中处理 204 响应?的主要内容,如果未能解决你的问题,请参考以下文章
Spring WebFlux Reactive 和 Kotlin Coroutines 启动错误
有没有办法在 Kotlin 中使用 coroutines/Flow/Channels 实现这个 rx 流?
Kotlin Coroutines 选择 Dispatcher