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)