在 Kotlin 中将枚举字段序列化为 JSON

dar*_*ico 15 jackson kotlin

我有一个愚蠢的问题,让我有点震惊。我有一个枚举和一个像这样的数据类:

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

data class MyEvent(
    val id: String,
    val event: MyEventType
)
Run Code Online (Sandbox Code Playgroud)

我需要将其作为 json 字符串发送,但常见的 desearilizer 会生成这样的 json

{ 
    "id": "identifier",
    "event": "FIRST"
}
Run Code Online (Sandbox Code Playgroud)

但是我需要

{ 
    "id": "identifier",
    "event": "firstEventReceived"
}
Run Code Online (Sandbox Code Playgroud)

据我了解,kotlin 允许重写数据类中的 getter,但我没有成功......

data class MyEvent(
    val id: String
) {
    val event: MyEventType get() event.typeName
}
Run Code Online (Sandbox Code Playgroud)

但我想我错过了一些东西......

Ada*_*hip 17

最简单的方法可能是用以下方式注释属性@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) }
}
Run Code Online (Sandbox Code Playgroud)

印刷:

{"id":"foo","event":"firstEventReceived"}
Run Code Online (Sandbox Code Playgroud)


Nik*_*kov 14

对于“Kotlin Serialization”库,您可以使用@SerialName注释:

@Serializable
enum class ConnectionStatus {

    @SerialName("open")
    OPEN,
    
    @SerialName("connecting")
    CONNECTING,
    
    @SerialName("closed")
    CLOSED
}
Run Code Online (Sandbox Code Playgroud)

  • 请注意,枚举应注释为“@Serializable”以与“@SerialName”一起使用 (3认同)

Lak*_*gha 5

最简单的方法是用 进行typeName注释@JsonValue。这将根据需要序列化和反序列化枚举字段。

enum class MyEventType(@JsonValue val typeName: String) {
    FIRST("firstEventReceived");
}
Run Code Online (Sandbox Code Playgroud)

另一种方法是使用@JsonFormat(如果您使用的 jackson 版本 < 2.9);


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

这是一个例子;

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

        val event = mapper.readValue<MyEvent>(json)
        println(event)
    }
Run Code Online (Sandbox Code Playgroud)

你得到输出;

{"id":"1","event":"firstEventReceived"}
MyEvent(id=1, event=FIRST)
Run Code Online (Sandbox Code Playgroud)

我使用杰克逊版本2.12.0。这是关于 Jackson 的枚举操作的好读物 - https://www.baeldung.com/jackson-serialize-enums