Tom
Tom

Reputation: 1507

Kotlin class to match JSON with Nested Object for GSON builder

I have some incoming JSON that looks like this.

 {  "status":200,
    "transformation_percent":0.0,
    "image_percent":24.51,
    "bandwidth_percent":0.0,
    "storage_percent":26.23,
    "freeTrialPeriod":7889238000,
    "freeTrialParams":"{\"cache_period\":604800000,\"cache_allowance\":5000,\"price_in_cents\":0}",
    "basicPlanParams":"{\"cache_period\":604800000,\"cache_allowance\":10000,\"stripe_plan_id\":\"plan_blah\",\"price_in_cents\":100,\"currency\":\"eur\"}"
}

I am trying to construct a ServerParams Kotlin class that will match this incoming JSON, so that I can pass the class to the gsonBuilder like this:

val GSON = GsonBuilder().setLenient().create()
val server_params = GSON.fromJson(string, ServerParams::class.java)

I am struggling with the nested objects. I know how to write my own deserializer, so I can do that if I have to, but Kotlin has proven to be such an elegant language in my short experience that I thought there must be a better way of doing it. I also don't want to have to write matching deserializers for every API call!

I've tried inner classes, which didn't work. I've tried creating additional classes for the nested objects in the JSON string and that didn't work either.

Upvotes: 0

Views: 943

Answers (1)

Willi Mentzel
Willi Mentzel

Reputation: 29864

Here is a minimal example of how you would do it:

class OuterClass(val name: String) {
    var inner = InnerClass(2)
}

class InnerClass(val number: Int)

fun main() {
    val gson = GsonBuilder().setLenient().create()
    val outerClass  = gson.fromJson("""{
        name: 'test',
        inner: {
            number : 1
        }
    }""".trimMargin(), OuterClass::class.java)
}

You just put the instance of the inner class in a property of the outer class.

Since Gson mutates the classes via reflection you could also declare the inner class as lateninit which would make the instantiation of the inner class with a default value unecessary.

class OuterClass(val name: String) {
    lateinit var inner: InnerClass
}

This, of course, only makes sense if you only instatiate the class via Gson.

Upvotes: 1

Related Questions