0

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()
Karan Dhillon
  • 1,186
  • 1
  • 6
  • 14
  • https://stackoverflow.com/a/24868996/2801237 I found something similar, is this what you are looking for? – mawalker May 04 '20 at 01:28
  • This is not relevant to my question. The OP uses run time polymorphism, while I am dealing with deserialization inconsistency. – Karan Dhillon May 04 '20 at 01:30
  • I'm confused by what you are saying. Perhaps if you gave an exmaple of the replies in json format it would be clearer. Because, as far as I can tell, they are facing the same problem as you are. Just have a different way of solving it. – mawalker May 04 '20 at 01:33
  • Edited the answer to make it clear. Instead of making two different subTypes, I rather do this with GSON Deserializer as I believe that is a better approach. If I wanted to use shortcuts or hacky ways, than I could've simply made two model classes. But I want to solve it the way this problem should be solved. – Karan Dhillon May 04 '20 at 01:38
  • Does this answer your question? [How Parse JSON using GSON WHen object is either JSONObject or JSONArray](https://stackoverflow.com/questions/24830699/how-parse-json-using-gson-when-object-is-either-jsonobject-or-jsonarray) didn't know it would create a message here when flagged for duplicate, but I do believe this is the easist/simpliest way to solve this. – mawalker May 04 '20 at 01:40

0 Answers0