Я получаю ответ от сервера на основе такой структуры:
{
"success":true,
"data":{"can be some kind of data, array or error message"}
}
Как правильно сопоставить атрибут данных в таких ситуациях?
Мои попытки заключались в использовании любого типа и приведении к указанному типу:
data class GeneralResponseModel(
val success: Boolean,
val data: Any
)
Средний
//
val response = gson.fromJson(it[0].toString(), GeneralResponseModel::class.java)
//
ViewModel
////////
if (res.success) {
isLoading.postValue(false)
///////
} else {
val result = res.data as ResponseError
errorMessage.postValue(ErrorWrapper(ErrorType.REQUEST_ERROR,result.detail,result.title))
isLoading.postValue(false)
}
///////////
И я получил
io.reactivex.exceptions.OnErrorNotImplementedException:
com.google.gson.internal.LinkedTreeMap не может быть приведен к
com.myapp.model.response.ResponseError
Другая попытка заключалась в использовании пустого интерфейса, который был реализован всеми возможными типами ответов. В этой ситуации я получил
java.lang.RuntimeException: невозможно вызвать конструктор без аргументов для
интерфейс com.myapp.model.response.Response.
Регистрация InstanceCreator в Gson для этого типа может исправить это
проблема.
Я не уверен, как правильно обращаться с таким тривиальным делом. Любые ссылки, примеры кода или помощь приветствуется. Заранее спасибо.
Обновление
Благодаря Никласу я пересмотрел gson на такую структуру:
lateinit var gson: Gson
when (methodName) {
RequestList.LOGIN.methodName -> {
gson =
GsonBuilder().registerTypeAdapter(
GeneralResponseModel::class.java,
object : JsonDeserializer<GeneralResponseModel> {
override fun deserialize(
json: JsonElement?,
typeOfT: Type?,
context: JsonDeserializationContext?
): GeneralResponseModel {
val gsonInner = Gson()
val jsonObject: JsonObject = json!!.asJsonObject
lateinit var generalResponseModel: GeneralResponseModel
generalResponseModel = if (!jsonObject.get("success").asBoolean) {
GeneralResponseModel(
false,
gsonInner.fromJson(jsonObject.get("data"), ResponseError::class.java)
)
} else {
GeneralResponseModel(
true,
gsonInner.fromJson(jsonObject.get("data"), DriverData::class.java)
)
}
return generalResponseModel
}
}).create()
}
RequestList.GET_JOBS.methodName -> {
gson = GsonBuilder().registerTypeAdapter(
GeneralResponseModel::class.java,
object : JsonDeserializer<GeneralResponseModel> {
override fun deserialize(
json: JsonElement?,
typeOfT: Type?,
context: JsonDeserializationContext?
): GeneralResponseModel {
val gsonInner = Gson()
val jsonObject: JsonObject = json!!.asJsonObject
lateinit var generalResponseModel: GeneralResponseModel
generalResponseModel = if (!jsonObject.get("success").asBoolean) {
GeneralResponseModel(
false,
gsonInner.fromJson(jsonObject.get("data"), ResponseError::class.java)
)
} else {
GeneralResponseModel(
true,
gsonInner.fromJson(jsonObject.get("data"), Array<JobResponse>::class.java)
)
}
return generalResponseModel
}
}).create()
}
else -> gson = Gson()
}