android 如何使用Kotlin协程处理改造中的204响应?

nnsrf1az  于 2023-02-27  发布在  Android
关注(0)|答案(5)|浏览(188)

我使用的是带有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响应而不崩溃?

axr492tv

axr492tv1#

据此,在改型方法声明中使用Response<Unit>
retrofit no content issue

w7t8yxp5

w7t8yxp52#

您可以使用Response<Unit>来处理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!
    }
mzmfm0qo

mzmfm0qo3#

使用示例代码解释@Dmitri的答案:
1.在APIInterface中,像这样调用API,

@GET(AppConstants.APIEndPoints.GET_NEWS)
 suspend fun getNews(
     @Query("limit") limit: String,
 ): Response<NewsListResponseModel>

其中,响应为retrofit2.Response
1.从调用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))
 }
olqngx59

olqngx594#

使用自定义拦截器将204的更改为200的对我很有效

class Code204Interceptor : Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        val request = chain.request()
        val response = chain.proceed(request)

        return if (response.code == 204) {
            response.newBuilder().code(200).build()
        } else {
            response
        }
    }
}
um6iljoc

um6iljoc5#

这可能会帮助某人在okhttp客户端构建器(示例化改型示例)中,我们添加了标头。我添加了错误的标头,导致HTTP 400 Bad request错误,删除以下内容对我有效。

.addHeader("Content-Encoding", "UTF-8")
      .header("Accept-Encoding", "identity")

相关问题