我尝试在here中的java中阅读这个类似的线程。 所以我在那里尝试了接受的答案,但它不起作用。这是我的问题
我将从端点获得两个不同的 JSON 响应。如果我成功获取餐厅数据,JSON 将是这样的
{
"R": {
"has_menu_status": {
"delivery": -1,
"takeaway": -1
},
"res_id": 18941862,
"is_grocery_store": false
},
"id": "18941862",
"name": "Pizza Maru",
"url": "https://www.zomato.com/jakarta/pizza-maru-1-thamrin?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1",
"location": {
"address": "Grand Indonesia Mall, East Mall, Lantai 3A, Jl. M.H. Thamrin No. 1, Thamrin, Jakarta",
"locality": "Grand Indonesia Mall, Thamrin",
"city": "Jakarta",
"city_id": 74,
"latitude": "-6.1955810000",
"longitude": "106.8213770000",
"zipcode": "",
"country_id": 94,
"locality_verbose": "Grand Indonesia Mall, Thamrin, Jakarta"
},
"switch_to_order_menu": 0,
"cuisines": "Pizza",
"timings": "10 AM to 10 PM",
"average_cost_for_two": 180000,
"price_range": 3,
"currency": "IDR",
"thumb": "https://b.zmtcdn.com/data/pictures/chains/2/18941862/403aa36cb046e86a694e7989bb7cd545.jpg?fit=around%7C200%3A200&crop=200%3A200%3B%2A%2C%2A",
"has_online_delivery": 0,
"is_delivering_now": 0,
"store_type": "",
"phone_numbers": "021 3108656",
}
然后,如果我发送无效的restaurantID,那么我将收到如下错误 JSON 响应:
{
"code": 404,
"status": "Not Found",
"message": "Not Found"
}
这是我制作的数据类
data class Restaurant (
@SerializedName("id")
val id : Int = 0,
@SerializedName("name")
var name : String = "",
@SerializedName("url")
val url : String = "",
@SerializedName("location")
val location : Location = Location(),
@SerializedName("currency")
val currency : String = "",
@SerializedName("phone_numbers")
val phone_numbers : String = "",
@SerializedName("thumb")
val thumbnail : String = ""
)
成功响应
data class Location (
@SerializedName("address")
val address : String = "",
@SerializedName("city")
val city : String = "",
@SerializedName("latitude")
val latitude : Double = 0.0,
@SerializedName("longitude")
val longitude : Double = 0.0,
@SerializedName("zipcode")
val zipcode : String = ""
)
错误响应
data class ErrorResponse (
val code : Int,
val status : String,
val message : String
)
这是我的改造界面。我的想法是,我首先将其转换为 Any,然后将其向下转换为 Restaurant
或 ZomatoErrorResponse
interface RestaurantAPI {
@Headers("user-key: $USER_KEY_ZOMATO")
@GET("restaurant")
fun getRestaurantDetail(
@Query("res_id") id: Int
): Call<Any>
}
这是错误:
所以我像这样使用我的改造
val call = restaurantService.getRestaurantDetail(restaurantID)
call.enqueue(object: Callback<Any>{
override fun onResponse(call: Call<Any>, response: Response<Any>) {
if (response.isSuccessful) {
// this line is executed
Log.d("checkxxx","${response.body()}")
val restaurantData = response.body() as Restaurant // <-- but Error while casting Any to Restaurant in here
restaurant.postValue(restaurantData)
}
}
})
我的应用程序在那条线上崩溃了。但实际上我可以成功获取数据,但我无法将其转换到 Restaurant。
这里出了什么问题?
或者也许有比这个更好的方法
最佳答案
我终于可以使用下面的代码解决我的问题
val call = restaurantService.getRestaurantDetail(restaurantID)
call.enqueue(object: Callback<Any>{
override fun onResponse(call: Call<Any>, response: Response<Any>) {
if (response.isSuccessful) {
val gson = Gson()
val restaurantData = gson.fromJson(gson.toJson(response.body()), Restaurant::class.java)
} else {
val errorBody = response.errorBody() ?: return
val type = object : TypeToken<ErrorResponse>() {}.type
val errorResponse: ErrorResponse? = gson.fromJson(errorBody.charStream(), type)
val errorMessage = errorResponse?.message ?: "Unknown Error"
}
}
})
不要忘记将界面设置为像这样的任何
interface RestaurantAPI {
@Headers("user-key: $USER_KEY_ZOMATO")
@GET("restaurant")
fun getRestaurantDetail(
@Query("res_id") id: Int
): Call<Any> // <---- set to Any like this
}
就我而言,我有成功响应和错误响应。所以我需要像这样分开它。
但是如果你有 2 个成功的响应,但它有不同的 JSON,那么你需要对上面代码中的 restaurantData
执行 null 检查,如果 null 则将其映射到其他 POJO。
关于android - 如何在 Kotlin 中处理两个不同的 Retrofit 响应?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64020669/