I have looked into this issue, and tried to implement what i could find over the SO, but no luck. So is my problem:
Sometimes, in my JSON
response, I get the data
field as a JSON object
, and other times the data field as JSON array
. Technically this is a bad API design, however changing the API at this point is not feasible.
Two types of JSON responses by API
{
data: {
.
.
.
}
}
{
data : [
.
.
.
]
}
I have tried to implement the DataDeserializer
, however the GSON
still identifies the JSON response
as JSON object
and not able to use the DataDeserializer
:
Class DataDeserializer
class DataDeserializer : JsonDeserializer<List<Data<Any>>> {
override fun deserialize(
json: JsonElement,
typeOfT: Type?,
context: JsonDeserializationContext
): List<Data<Any>> {
val dataList = ArrayList<Data<Any>>()
when {
json.isJsonObject -> {
val data = context.deserialize<Data<Any>>(json.asJsonObject, Data::class.java)
dataList.add(data)
}
json.isJsonArray -> {
for (jsonObject in json.asJsonArray)
dataList.add(context.deserialize(jsonObject, Data::class.java))
}
else -> throw RuntimeException("Unexpected JSON Type: ${json.javaClass}")
}
return dataList
}
}
Model Classes
open class Json<T> {
lateinit var data: List<Data<T>>
fun getFirstChild() = data.first()
}
data class Data<T>(
private val id: String = "",
private val type: String = "",
val attributes: T
)
Registering DataDeserializer with GSONConverterFactory
val gson = GsonBuilder().registerTypeAdapter(Data::class.java, DataDeserializer()).create()