如何使用 Kotlin Coroutines 在 Retrofit 中处理 204 响应?
How to handle 204 response in Retrofit using Kotlin Coroutines?
我正在使用带有 Kotlin 协程的 Retrofit 2.7.1。
我有这样定义的 Retrofit 服务:
@PUT("/users/{userId}.json")
suspend fun updateUserProfile(
@Path("userId") userId: String,
@Query("display_name") displayName: String) : Void
此调用 returns HTTP 204 无内容 响应,导致 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.onResponse(KotlinExtensions.kt:43)
at retrofit2.OkHttpCall.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 响应而不崩溃?
据此,在retrofit方法声明中使用Response<Unit>
您可以使用 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!
}
用示例代码解释@Dmitri 的答案:
在你的API界面中,像这样调用你的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))
}
这可能对某人有帮助
我添加了错误的 headers 导致我出现 HTTP 400 Bad request 错误。
.addHeader("Content-Encoding", "UTF-8")
.header("Accept-Encoding", "identity")
我正在使用带有 Kotlin 协程的 Retrofit 2.7.1。
我有这样定义的 Retrofit 服务:
@PUT("/users/{userId}.json")
suspend fun updateUserProfile(
@Path("userId") userId: String,
@Query("display_name") displayName: String) : Void
此调用 returns HTTP 204 无内容 响应,导致 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.onResponse(KotlinExtensions.kt:43)
at retrofit2.OkHttpCall.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 响应而不崩溃?
据此,在retrofit方法声明中使用Response<Unit>
您可以使用 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!
}
用示例代码解释@Dmitri 的答案:
在你的API界面中,像这样调用你的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)) }
这可能对某人有帮助 我添加了错误的 headers 导致我出现 HTTP 400 Bad request 错误。
.addHeader("Content-Encoding", "UTF-8")
.header("Accept-Encoding", "identity")