使用 kotlin 序列化使用 "non-stable" 值反序列化 JSON



BE中的JSON结构不太好(我无法更改(,它以前是用moshi(问题的自定义适配器(处理的。现在我尝试使用纯kotlin序列化,但正如前面所说,JSON结构对我没有太大帮助。

{
"foo": {
"version":1,
"mask": [
{
"values": [
{ "bar": 1, ... }
]
},
{
"values": [
"important text i guess"
]
},
]
}
}

现在,正如您所看到的,我的问题是,它可以包含对象字符串。所有这些都应该解析到kotlin中,其中如下所示:

data class Values(
val bar: Int? = null,
val text: String? = null,
...
)

理论上,我可以更改本地实现,例如拆分类之类的。我已经尝试过应用多态反序列化,但据我所知,如果没有在JSON中设置classDiscriminator,它无法识别的两个后代之间的差异。

有什么好建议吗?

更新

我尝试的多态版本(以防我只是犯了一些错误(

@Polymorphic
@Serializable
sealed class Values{

@Serializable
data class ObjectValues(
val bar: Int? = null,
...
)
@Serializable
data class TextValues(
val text: String? = null
)
}

并使用它:

Json {
ignoreUnknownKeys = true
serializersModule = SerializersModule {
polymorphic(Values::class) {
subclass(Values.ObjectValues::class, Values.ObjectValues.serializer())
subclass(Values.TextValues::class, Values.TextValues.serializer())
}
}

错误:

Polymorphic serializer was not found for missing class discriminator ('null')
JSON input: {"bar":42,...}

免责声明我知道这会解决所有问题:(

"values": [ { "text":"important text i guess" } ]

拥有classDiscriminator不是多态反序列化的强制性要求。在这种情况下,可以使用基于内容的多态反序列化。

您只需要为Values类定义一个JsonContentPolymorphicSerializer,并使用一些逻辑来选择子类序列化程序:

object ValuesSerializer : JsonContentPolymorphicSerializer<Values>(Values::class) {
override fun selectDeserializer(element: JsonElement) = when {
element.jsonObject["values"]!!.jsonArray.first() is JsonObject -> ObjectValues.serializer()
else -> TextValues.serializer()
}
}

并将其连接为Values类的串行器:

@Serializable(with = ValuesSerializer::class)
sealed class Values
@Serializable
data class TextValues(val values: List<String>) : Values()
@Serializable
data class ObjectValues(val values: List<Bar>) : Values()
@Serializable
data class Bar(val bar: Int)
@Serializable
data class MyJson(val foo: Foo)
@Serializable
data class Foo(val version: Int, val mask: List<Values>)

无需serializersModule:

val result = Json.decodeFromString<MyJson>(json) 

最新更新