Сериализовать поле перечисления в JSON в Котлине

У меня есть глупый вопрос, который меня 9X_kotlin немного ошеломил. У меня есть перечисление 9X_jackson и класс данных вроде этого:

enum class MyEventType(val typeName: String) {
    FIRST("firstEventReceived")
}

data class MyEvent(
    val id: String,
    val event: MyEventType
)

Мне нужно отправить 9X_kotlin это как строку json, но обычный дезарилизатор 9X_kotlin делает такой json

{ 
    "id": "identifier",
    "event": "FIRST"
}

но мне нужно

{ 
    "id": "identifier",
    "event": "firstEventReceived"
}

Насколько я 9X_kotlin понимаю, kotlin позволяет переопределить 9X_kotlin геттер в классе данных, но мне это не удалось 9X_kotlin ... Попытка сделать

data class MyEvent(
    val id: String
) {
    val event: MyEventType get() event.typeName
}

но я что-то упустил, наверное 9X_jackson ...

7
0
3
Общее количество ответов: 3

Ответ #1

Ответ на вопрос: Сериализовать поле перечисления в JSON в Котлине

Вероятно, самый простой способ - аннотировать 9X_kotlin свойство с помощью @JsonValue:

enum class MyEventType(@JsonValue val typeName: String) {
    FIRST("firstEventReceived")
}

data class MyEvent(
    val id: String,
    val event: MyEventType
)


fun main() {
    MyEvent(id = "foo", event = MyEventType.FIRST)
        .let { jacksonObjectMapper().writeValueAsString(it) }
        .let { println(it) }
}

Распечатки:

{"id":"foo","event":"firstEventReceived"}

10
0

Ответ #2

Ответ на вопрос: Сериализовать поле перечисления в JSON в Котлине

Самый простой способ - аннотировать typeName с помощью 9X_jackson @JsonValue. Это приведет к сериализации и десериализации 9X_jackson поля перечисления по вашему желанию.

enum class MyEventType(@JsonValue val typeName: String) {
    FIRST("firstEventReceived");
}

Альтернативой 9X_kotlin является использование @JsonFormat (если вы используете 9X_jackson версию Jackson <2.9);


enum class MyEventType(@JsonFormat(shape = JsonFormat.Shape.OBJECT) val typeName: String) {
    FIRST("firstEventReceived");
}

Вот пример;

  @JvmStatic
    fun main(args: Array) {
        val mapper = jacksonObjectMapper()
        val json = mapper.writeValueAsString(MyEvent("1", MyEventType.FIRST))
        println(json)

        val event = mapper.readValue(json)
        println(event)
    }

Вы получаете 9X_kotlin результат;

{"id":"1","event":"firstEventReceived"}
MyEvent(id=1, event=FIRST)

Я использовал Jackson версии 2.12.0. Вот 9X_jackson хорошее прочтение о манипуляциях с перечислением 9X_kotlin с помощью Джексона - https://www.baeldung.com/jackson-serialize-enums

2
1

  • Да, [`readValue()`] (https://github.com/FasterXML/jackson-module-kotlin/blob/2.13/src/main/kotlin/com/fasterxml/jackson/module/kotlin/Extensions.kt # L39) из `jackson-module ...

Ответ #3

Ответ на вопрос: Сериализовать поле перечисления в JSON в Котлине

Также вы можете иметь enum с 2+ полями которые вы хотите 9X_kotlin сериализовать

enum class MyEventType(
        val firstField: String,
        val secondField: String,
        val thirdField: String
) {
        MY_ENUM("firstFieldValue", "secondFieldValue", "thirdFieldValue")
}

Вы можете выбрать один из следующих 9X_kotlin двух вариантов:

  1. Поместите @JsonValue над методом(давайте назовем 9X_kotlin его геттером), который вернет требуемое 9X_jackson значение(если вам нужна только часть полей):

    @JsonValue
    fun getSerializedObject(): String {
            return "{firstField: $firstField, thirdField: $secondField}"
    }
    

    Результат будет "{firstField: firstFieldValue, thirdField: thirdFieldValue}"

  2. Поместите @JsonFormat(shape = JsonFormat.Shape.OBJECT) над вашим классом enum (для 9X_kotlin класса сериализации как общего класса):

     @JsonFormat(shape = JsonFormat.Shape.OBJECT)
     enum class MyEventType(
             val firstField: String,
             val secondField: String,
             val thirdField: String
     ) {
             MY_ENUM("firstField", "secondField", "thirdField")
     }
    

    Результат 9X_jackson будет "{"firstField": "firstFieldValue", "secondField": "secondFieldValue", "thirdField": "thirdFieldValue"}"

1
0