giozh
giozh

Reputation: 10068

Retrofit2 and Gson, deserialize data inside a certain json element

Inside my app i call some remote APIs that give me a response wrapped into a useless "root" json element. I Paste you an example of json response

{
 "response": {
     "status": {
         //here status fields, common to all responses
      },
      "configuration": {
          //here configurations fields
      }
  }
}

I'm using an Android studio extension for generate kotlin data classes (JsonToKotlinClass) and i obtain four kotlin classes:

-MyResponseClass, Response, Status, Configuration

where MyResponseClass is like

data class MyResponseClass(
    val response: Response
)

there's a way to avoid creation of "Response" class by parsing only it's relative json content and get a MyResponseClass look like like

data class MyResponseClass(
    val status:Status,
    val configuration: Configuration
)

?

Upvotes: 0

Views: 826

Answers (2)

Manu
Manu

Reputation: 422

From the title of your question I am assuming that you want to automatically parse the json response to the to the simpler MyResponseClass

You can achieve this by using a type adapter for gson. In your case the adapter class will look similar to the following.

class MyResponseClassAdapter : JsonDeserializer<MyResponseClass> {
   override fun deserialize(jsonElement: JsonElement, p1: Type?, p2: JsonDeserializationContext?): MyResponseClass {
  val content = jsonElement.asJsonObject["response"]
  return  Gson().fromJson(content , MyResponseClass::class.java)
}
}

Then add this adapter to a gson instance and use that gson instance with your retrofit instance.

 val gson = GsonBuilder()
            .registerTypeAdapter(MyResponseClass::class.java, MyResponseClassAdapter ())
            .create()

 Retrofit.Builder()
            .addConverterFactory(GsonConverterFactory.create(gson))
            .baseUrl("{base_url}")
            .client(okHttp)
            .build()

Upvotes: 1

Joshua Best
Joshua Best

Reputation: 246

Yes, when you get the object, instead of converting it straight away, convert it like this

val jsonObject = JSONObject("data")
val innerObject = jsonObject.getJSONObject("status")

and then convert inner object with gson.

This can of course be minified like this:

val object = Gson().fromJson(JSONObject("response").getJSONObject("status"), MyResponseClass::class.java)

Upvotes: 0

Related Questions