![](/img/trans.png)
[英]How to get body from a server response with code 400 in Kotlin with coroutine and retrofit?
[英]How to handle error response return from server api in kotlin+retrofit+coroutine+mvvm
我从同一个端点有两个不同的响应。 一种是实际成功结果数据模型,一种是错误响应模型。 两个json结构都是这样的:
成功响应:
{
"result":{
"id":1,
"name_en":"Stack Over Flow",
"summary":"Stack Overflow is the largest, most trusted online community for developers to learn, share their programming knowledge, and build their careers."
}
}
错误响应:
{
"message": "Login Failed"
}
我可以处理成功响应,但无法显示从服务器获得的错误消息。 我尝试了很多方法,但我做不到。 在这里我分享我的一些方面我做了什么
主视图模型.kt
var job: Job? = null
val myDataResponse: MutableLiveData<HandleResource<DataResponse>> =MutableLiveData()
fun myData() {
job = CoroutineScope(Dispatchers.IO).launch {
val myDataList = mainRepository.myData()
withContext(Dispatchers.Main) {
myDataResponse.postValue(handleMyDataResponse(myDataList))
}
}
}
private fun handleMyDataResponse(myDataResponse: Response<DataResponse>): HandleResource<DataResponse>? {
if (myDataResponse.isSuccessful) {
myDataResponse.body()?.let { myDataData ->
return HandleResource.Success(myDataData)
}
}
return HandleResource.Error(myDataResponse.message())
}
我需要一个解决方案,而服务器给我错误消息我想在我的正面显示相同的错误消息。 我怎样才能做到这一点?
private fun handleMyDataResponse(myDataResponse: Response<DataResponse>): HandleResource<DataResponse>? {
myDataResponse.body()?.let { myDataData ->
if (myDataResponse.code() == 200) {
return HandleResource.Success(myDataData )
} else {
val rawResponse = myDataData.string()
return HandleResource.Error(getErrorMessage(rawResponse))
}
}
}
fun getErrorMessage(raw: String): String{
val object = JSONObject(raw);
return object.getString("message");
}
响应的主体(成功或失败)是 response.body()。 如果你想把它作为一个字符串来获取,那么调用 response.body().string()。 由于您想从响应中读取消息对象,因此需要将其转换为 Json。
如果您遵循 MVVM 模式,那么我建议为 API 调用创建一个密封类。
处理 api 成功和失败或网络问题。 资源类将是通用的,因为它将处理所有类型的 api 响应
sealed class Resource<out T> {
data class Success<out T>(val value: T): Resource<T>()
data class Failure(
val isNetworkErro: Boolean?,
val errorCode: Int?,
val errorBody: ResponseBody?
): Resource<Nothing>()
}
在调用 API 时在基础存储库上,无论成功还是失败,您都可以返回资源。
abstract class BaseRepository {
suspend fun <T> safeApiCall(
apiCall: suspend () -> T
): Resource<T>{
return withContext(Dispatchers.IO){
try {
Resource.Success(apiCall.invoke())
} catch (throwable: Throwable){
when (throwable){
is HttpException -> {
Resource.Failure(false,throwable.code(), throwable.response()?.errorBody())
}
else ->{
Resource.Failure(true, null, null)
}
}
}
}
}
}
如果您遵循此模式,您将能够处理所有失败和成功响应,我希望这会有所帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.