gpt4 book ai didi

json - 使用 kotlinx.serialization 序列化 Java Path

转载 作者:行者123 更新时间:2023-12-04 17:20:41 27 4
gpt4 key购买 nike

使用 kotlinx.serialization,这段代码会抛出一个错误:println(Json.encodeToString(Path.of("value")))kotlinx.serialization.SerializationException: Class 'WindowsPath' is not registered for polymorphic serialization in the scope of 'Path'.

WindowsPath 是内部的,因此我无法将其注册为多态子类(如 this example 中所示),只能使用 Path 本身,甚至 Path 的自定义 KSerializer 也会引发完全相同的错误。
有什么方法可以让 Path 正确序列化/反序列化而不必将其存储为字符串?

最佳答案

Path是一个接口(interface),因此它可以使用 PolymorphicSerializer 策略隐式序列化。此策略要求您为实现它的子类注册序列化程序,但如您所知,在这种情况下这是不可能的。有一个 default polymorphic serializer ,但它仅影响反序列化过程,并且仅在反序列化值是 JSONObject 时才有效。

对于下面的序列化器

object PathAsStringSerializer : KSerializer<Path> {
override val descriptor = PrimitiveSerialDescriptor("Path", PrimitiveKind.STRING)

override fun serialize(encoder: Encoder, value: Path) = encoder.encodeString(value.toAbsolutePath().toString())

override fun deserialize(decoder: Decoder): Path = Path.of(decoder.decodeString())
}
\\Not working
val module = SerializersModule { polymorphicDefault(Path::class) { PathAsStringSerializer } }
val decoded : Path = Json { serializersModule = module }.decodeFromString("C:\\Temp")

它会抛出运行时异常kotlinx.serialization.json.internal.JsonDecodingException: Expected class kotlinx.serialization.json.JsonObject as the serialized body of kotlinx.serialization.Polymorphic<Path>, but had class kotlinx.serialization.json.JsonLiteral

所以,它不能用普通的方式序列化,它的序列化/反序列化有3种情况需要处理:

<强>1。简单的连载Path变量

在这种情况下,您需要显式传递您的自定义序列化程序:

val path = Path.of("C:\\Temp")

val message1 = Json.encodeToString(PathAsStringSerializer, path).also { println(it) }
println(Json.decodeFromString(PathAsStringSerializer, message1))

<强>2。类的序列化,使用 Path作为通用参数

在这种情况下,您需要定义单独的序列化程序(您可以引用原始 PathAsStringSerializer )并显式传递它们:

object ListOfPathsAsStringSerializer : KSerializer<List<Path>> by ListSerializer(PathAsStringSerializer)

val message2 = Json.encodeToString(ListOfPathsAsStringSerializer, listOf(path)).also { println(it) }
println(Json.decodeFromString(ListOfPathsAsStringSerializer, message2))
@Serializable
data class Box<T>(val item: T)
object BoxOfPathSerializer : KSerializer<Box<Path>> by Box.serializer(PathAsStringSerializer)

val message3 = Json.encodeToString(BoxOfPathSerializer, Box(path)).also { println(it) }
println(Json.decodeFromString(BoxOfPathSerializer, message3))

3.具有上述类型字段的类序列化

在这种情况下,您需要添加恭敬的 @Serializable(with = ...)这些字段的注释:

@Serializable
data class InnerObject(
@Serializable(with = ListOfPathsAsStringSerializer::class)
val list: MutableList<Path> = mutableListOf(),
@Serializable(with = PathAsStringSerializer::class)
val path: Path,
@Serializable(with = BoxOfPathSerializer::class)
val box: Box<Path>
)

或者只是 list them once for a whole file :

@file: UseSerializers(PathAsStringSerializer::class, ListOfPathsAsStringSerializer::class, BoxOfPathSerializer::class)

对于这种情况,插件生成的序列化程序就足够了:

val message4 = Json.encodeToString(InnerObject(mutableListOf(path), path, Box(path))).also { println(it) }
println(Json.decodeFromString<InnerObject>(message4))

关于json - 使用 kotlinx.serialization 序列化 Java Path,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66355506/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com