Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin data class create dynamically json of its fields using GSON

I have a data class like this:

data class TestModel(
     val id: Int, 
     val description: String, 
     val picture: String)

If I create JSON from this data class using GSON and it generates a result like this

{"id":1,"description":"Test", "picture": "picturePath"}

What to do if I need the following JSON from my data class:

{"id":1, "description":"Test"}

And other times:

`{"id":1, "picture": "picturePath"}

` Thanks in advance!

like image 868
nAkhmedov Avatar asked Mar 06 '26 13:03

nAkhmedov


1 Answers

You can solve this problem with writing custom adapter and with optional types:

import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.google.gson.TypeAdapter
import com.google.gson.stream.JsonReader
import com.google.gson.stream.JsonToken
import com.google.gson.stream.JsonWriter

data class TestModel(
    val id: Int,
    val description: String? = "",
    val picture: String? = "")

class TesModelTypeAdapter : TypeAdapter<TestModel>() {
    override fun read(reader: JsonReader?): TestModel {
        var id: Int? = null
        var picture: String? = null
        var description: String? = null

        reader?.beginObject()
        while (reader?.hasNext() == true) {
            val name = reader.nextName()

            if (reader.peek() == JsonToken.NULL) {
                reader.nextNull()
                continue
            }

            when (name) {
                "id" -> id = reader.nextInt()
                "picture" -> picture = reader.nextString()
                "description" -> description = reader.nextString()
            }
        }
        reader?.endObject()

        return when {
            !picture.isNullOrBlank() && description.isNullOrBlank() -> TestModel(id = id ?: 0, picture = picture)
            !description.isNullOrBlank() && picture.isNullOrBlank() -> TestModel(id = id ?: 0, description = description)
            else -> TestModel(id ?: 0, picture, description)
        }
    }

    override fun write(out: JsonWriter?, value: TestModel?) {
        out?.apply {
            beginObject()

            value?.let {
                when {
                    !it.picture.isNullOrBlank() && it.description.isNullOrBlank() -> {
                        name("id").value(it.id)
                    name("picture").value(it.picture)
                    }
                    !it.description.isNullOrBlank() && it.picture.isNullOrBlank() -> {
                        name("id").value(it.id)
                    name("description").value(it.description)
                    }
                    else -> {
                        name("id").value(it.id)
                        name("picture").value(it.picture)
                    name("description").value(it.description)
                    }
                }
            }

            endObject()
        }
    }
}

class App {
    companion object {
        @JvmStatic fun main(args: Array<String>) {
            val tm = TestModel(12, description = "Hello desc")
            val tm2 = TestModel(23, picture = "https://www.pexels.com/photo/daylight-forest-glossy-lake-443446/")
            val tm3 = TestModel(12, "Hello desc", "https://www.pexels.com/photo/daylight-forest-glossy-lake-443446/")

            val gson = GsonBuilder().registerTypeAdapter(TestModel::class.java, TesModelTypeAdapter()).create()

            System.out.println(gson.toJson(tm))
            System.out.println(gson.toJson(tm2))
            System.out.println(gson.toJson(tm3))
        }
    }
}

enter image description here

like image 196
SBotirov Avatar answered Mar 08 '26 12:03

SBotirov



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!