如何从自定义改造异常处理程序中提取(成功的)响应主体

How can I extract the (successful) response body from a custom retrofit exception handler

我遵循 this guide and found 使用 Retrofit 处理网络异常。虽然它们都非常有用,但其中 none 解释了如何提取成功请求的正文。下面是一段代码,可以更好地解释我要完成的任务:

两个例子中密封的class保持不变...

// exception handling:
sealed class NetworkResponse<out T : Any, out U : Any> {

    data class Success<T : Any>(val body: T) : NetworkResponse<T, Nothing>()

    data class ApiError<U : Any>(val body: U, val code: Int) : NetworkResponse<Nothing, U>()

    data class NetworkError(val error: IOException) : NetworkResponse<Nothing, Nothing>()

    data class UnknownError(val error: Throwable) : NetworkResponse<Nothing, Nothing>()
}

但我不清楚在成功调用时提取正文。这是我的尝试:

val oAuthRetrofit: Retrofit = Retrofit.Builder()
    .baseUrl(OAUTH_BASE_URL)
    .addConverterFactory(Json.asConverterFactory(contentType))
    .build()
val salesforceOAuthAPI: SalesforceInterface =
    oAuthRetrofit.create(SalesforceInterface::class.java)

val oAuthAccessTokenResponse: NetworkResponse<OAuthAccessTokenResponse, Error> =
    salesforceOAuthAPI.getOAuthAccessToken(
        GRANT_TYPE,
        BuildConfig.SALESFORCE_CLIENT_ID,
        BuildConfig.SALESFORCE_CLIENT_SECRET,
        BuildConfig.SALESFORCE_USERNAME,
        BuildConfig.SALESFORCE_PASSWORD + BuildConfig.SALESFORCE_SECURITY_TOKEN
    )

val body = oAuthAccessTokenResponse.body  // Unresolved reference
// Use body()

如何提取成功请求的正文?

为像 BaseResponse 这样的响应模型创建新的class

data class BaseResponse (
    val message: String? = "",
    val code: Int? = 0,
)

当请求成功时,将改装响应的值传递给您使用的通用 class

NetworkResponse.Success(response)

和post将此值添加到实时数据并在视图中观察此实时数据。

在媒体 post 中您可以访问 Source Code 在那里您可以检查您遗漏了什么。

回答您的问题

How can I extract the body of a successful request?

您可以简单地这样做:

val response1 = salesforceOAuthAPI.getWhatever()
when (response1) {
      is NetworkResponse.Success -> Log.d(TAG, "Success ${response1.body.name}")
      is NetworkResponse.ApiError -> Log.d(TAG, "ApiError ${response1.body.message}")
      is NetworkResponse.NetworkError -> Log.d(TAG, "NetworkError")
      is NetworkResponse.UnknownError -> Log.d(TAG, "UnknownError")
}

并且在 NetworkResponse.Success 中你有你想要的数据,但是因为你使用 sealed class 来检测错误和数据,你不知道那个对象里面有什么直到你做了 when.

顺便说一句,不知道你是否关注了所有 post 但你错过了

.addCallAdapterFactory(NetworkResponseAdapterFactory())

Retrofit.Builder() 中,否则它不会执行 magic 将所有内容封装到 NetworkResponse