我有几个类要反序列化,其中包括多态类型列表。我可以让它反序列化正确的已知类型,但是反序列化未知类型会引发异常。我真正想要的是,列表只包含已知类型,未知类型只是过滤掉。如果能以通用的方式做到这一点,那就更好了。
sealed interface BaseInterface
interface I1 : BaseInterface {
fun f1(): String
}
interface I2: BaseInterface {
fun f2(): String
}
@Serializable
@SerialName("i1")
data class I1Rest(value: String): I1 {
fun f1(): String = value
}
@Serializable
@SerialName("i2")
data class I2Rest(value: String): I2 {
fun f2(): String = value
}
@Serializable
data class SomeClass(list: List<BaseInterface>)如何正确地反序列化SomeClass
{ "list": [ {"type": "i1", "value": "v1" }, {"type": "i2", "value": "v2" }, {"type": "i3", "value": "v3" } ] }如果我不将i3类型添加到json中,则可以使用
SerializersModule {
polymorphic(BaseInterface::class){
subclass(I1Rest::class)
subclass(I2Rest::class)
}
}但一旦我包括了一个未知类型,它就会破裂。请注意,我不希望将未知数反序列化为默认类型(必须扩展基本密封接口)。我想要的是忽略/过滤那些未知数。(最好是以泛型的方式),我还想将BaseInterface保留为接口而不是类,因为我只想公开接口,而不想公开具体的类(这是用于lib的)
发布于 2022-03-31 08:33:18
好吧,这是我能想到的最好的了:
@Serializable
data class SomeClass(
@Serializable(with = UnknownBaseInterfaceTypeFilteringListSerializer::class)
val list: List<BaseInterface>
)
val json = Json {
ignoreUnknownKeys = true
serializersModule = SerializersModule {
polymorphic(BaseInterface::class) {
subclass(I1Rest::class)
subclass(I2Rest::class)
defaultDeserializer { UnknownTypeSerializer() }
}
}
}
class FilteringListSerializer<E>(private val elementSerializer: KSerializer<E>) : KSerializer<List<E>> {
private val listSerializer = ListSerializer(elementSerializer)
override val descriptor: SerialDescriptor = listSerializer.descriptor
override fun serialize(encoder: Encoder, value: List<E>) {
listSerializer.serialize(encoder, value)
}
override fun deserialize(decoder: Decoder): List<E> = with(decoder as JsonDecoder) {
decodeJsonElement().jsonArray.mapNotNull {
try {
json.decodeFromJsonElement(elementSerializer, it)
} catch (e: UnknownTypeException) {
null
}
}
}
}
class UnknownTypeException(message: String) : SerializationException(message)
open class UnknownTypeSerializer<T> : KSerializer<T> {
override val descriptor: SerialDescriptor = buildClassSerialDescriptor("Nothing")
override fun deserialize(decoder: Decoder): T = throw UnknownTypeException("unknown type")
override fun serialize(encoder: Encoder, value: T) = throw UnknownTypeException("unknown type")
}
object UnknownBaseInterfaceTypeFilteringListSerializer : KSerializer<List<BaseInterface>> by FilteringListSerializer(PolymorphicSerializer(BaseInterface::class))https://stackoverflow.com/questions/71654470
复制相似问题