有没有一种方法可以在 Kotlinx-Serialization 中序列化一个 Map?

9

我正在使用 Kotlin 1.3.10(并且受此版本限制),以及 Kotlinx-Serialization 0.13,我遇到了在 Kotlinx-Serialization 中序列化映射的问题。

我有以下代码:

@Serializer(forClass = LocalDate::class)
object LocalDateSerializer : KSerializer<LocalDate> {
    private val formatter: DateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
    override val descriptor: SerialDescriptor
        get() = StringDescriptor.withName("LocalDate")
    override fun serialize(encoder: Encoder, obj: LocalDate) {
        encoder.encodeString(obj.format(formatter))
    }
    override fun deserialize(decoder: Decoder): LocalDate {
        return LocalDate.parse(decoder.decodeString(), formatter)
    }
}

@Serializable
data class MyClass (
    val students: Map<String,LocalDate>
)

@UnstableDefault
@Test
fun decodeEncodeSerialization() {
    val jsonParser = Json(
        JsonConfiguration(
            allowStructuredMapKeys = true
        )
    )
    val mc = MyClass(
        mapOf("Alex" to LocalDate.of(1997,2,23))
        )

    val mcJson = jsonParser.stringify(MyClass.serializer(), mc)
    val mcObject = jsonParser.parse(MyClass.serializer(), mcJson)

    assert(true)
}

在检查代码时,有一条红线,上面写着“找不到‘LocalDate’的序列化程序。要使用上下文序列化程序作为回退,请明确注释类型或属性@ContextualSerialization。”

对于其他类型的字段,只需添加@Serialization即可。

@Serializable
data class Student (
    val name: String,
    @Serializable(with = LocalDateSerializer::class)
    val dob: LocalDate
)

但是我似乎无法使用地图找出如何做到。我将其放在对象上方或旁边...

@Serializable
data class MyClass (
    val students: Map<String,@Serializable(with = LocalDateSerializer::class) LocalDate> //here
    //or 
    //@Serializable(with = LocalDateSerializer::class)
    //val students2: Map<String, LocalDate> //here 
)

...但是测试仍然失败并出现错误:

kotlinx.serialization.SerializationException: 找不到类java.time.LocalDate的无参序列化程序(Kotlin反射不可用)。对于诸如列表之类的通用类,请显式提供序列化程序。

我的解决方法是

@Serializable
data class MyClass (
    val students: List<Student>
)
@Serializable
data class Student (
    val name: String,
    @Serializable(with = LocalDateSerializer::class)
    val dob: LocalDate
)

有没有不用绕过去的方法呢?谢谢!

1个回答

1
@file:UseSerializers(LocalDateSerializer::class)

将此代码放入声明对象的文件中,它应该在每次看到Local Date时使用LocalDateSerializer。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接