Класс данных Kotlin создает динамически JSON своих полей, используя GSON - PullRequest
0 голосов
/ 27 ноября 2018

У меня есть такой класс данных:

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

Если я создаю JSON из этого класса данных, используя GSON, и он генерирует такой результат

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

Что делать, еслиМне нужен следующий JSON из моего класса данных:

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

И в других случаях:

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

`Заранее спасибо!

Ответы [ 3 ]

0 голосов
/ 27 ноября 2018

Эту проблему можно решить с помощью написания настраиваемого адаптера и с дополнительными типами:

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

0 голосов
/ 28 ноября 2018

Я хочу дать вам альтернативные способы без сериализации / десериализации вручную.

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

Когда вы создаете JSON из класса данных

val params = TestModel(id = 1, description = "custom text")

или

val params = TestModel(id = 1, picture = "picture path")

Если одно из них является нулевым для класса данных, GSON пропускает это поле автоматически.

0 голосов
/ 27 ноября 2018

Вот на самом деле способ игнорировать поля, которые не отмечены аннотацией @Exposed.Чтобы это работало, при создании экземпляра Gson должна использоваться специальная конфигурация. Здесь , как вы можете это сделать.

Простой способ - пометить поле как @Transient.Тогда он не будет ни сериализован, ни десериализован.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...