如何从自定义Retrofit异常处理器中提取成功请求的响应体?
如何提取Retrofit成功请求的响应体(基于密封类封装)
我来帮你解决这个问题~你遇到的核心问题是:NetworkResponse作为密封类,不同子类拥有不同的专属属性——只有Success子类才包含body字段,直接通过父类对象访问body自然会报错,因为其他分支(比如ApiError、NetworkError)根本没有这个属性。
你需要通过类型判断区分不同的响应类型,在Success分支里安全提取响应体。Kotlin的when表达式是处理密封类的最佳选择,它能帮你穷尽所有可能的响应分支:
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 ) // 用when表达式处理所有响应分支 when (oAuthAccessTokenResponse) { is NetworkResponse.Success -> { // 这里已通过智能转换确定是Success类型,可安全访问body val responseBody = oAuthAccessTokenResponse.body // 在这里处理成功业务逻辑,比如保存token、跳转页面 println("获取Token成功:${responseBody.accessToken}") } is NetworkResponse.ApiError -> { // 处理API返回的业务错误(比如401权限不足、404资源不存在) println("API错误,状态码:${oAuthAccessTokenResponse.code},错误信息:${oAuthAccessTokenResponse.body}") } is NetworkResponse.NetworkError -> { // 处理网络层异常(比如无网络、连接超时) println("网络异常:${oAuthAccessTokenResponse.error.localizedMessage}") } is NetworkResponse.UnknownError -> { // 处理其他未知异常(比如解析失败、空指针) println("未知错误:${oAuthAccessTokenResponse.error.stackTraceToString()}") } }
补充说明
密封类的设计初衷就是让你明确处理所有可能的分支,避免遗漏异常场景。通过is关键字做类型判断后,Kotlin会自动进行智能类型转换,此时你无需额外强转,就能直接访问对应子类的专属属性(比如Success的body)。
另外要确认你的SalesforceInterface中,getOAuthAccessToken方法的返回类型确实是NetworkResponse<OAuthAccessTokenResponse, Error>(而非Retrofit原生的Call)——如果是通过自定义CallAdapter封装了Retrofit的请求结果,那上面的写法就是完全正确的。
内容的提问来源于stack exchange,提问作者Michael Schmidt
相关产品推荐
相关产品推荐

