Сериализовать поле перечисления в 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 ...
Ответ #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"}
Ответ #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
- Да, [`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 двух вариантов:
-
Поместите @JsonValue над методом(давайте назовем 9X_kotlin его геттером), который вернет требуемое 9X_jackson значение(если вам нужна только часть полей):
@JsonValue fun getSerializedObject(): String { return "{firstField: $firstField, thirdField: $secondField}" }
Результат будет
"{firstField: firstFieldValue, thirdField: thirdFieldValue}"
-
Поместите @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"}"
-
3
-
3
-
3
-
1
-
1
-
7
-
1
-
2
-
22
-
2
-
1
-
10
-
5
-
8
-
11
-
2
-
9
-
23
-
6
-
6
-
1
-
40
-
12
-
6
-
11
-
4
-
4
-
1
-
1
-
2
-
1
-
4
-
3
-
8
-
6
-
3
-
1
-
3
-
4
-
2
-
6
-
1
-
1
-
9
-
11
-
4
-
4
-
5
-
8
-
3