微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在 Kotlinx 序列化中序列化“任何”类型?

如何解决如何在 Kotlinx 序列化中序列化“任何”类型?

我有一个针对网络流量进行序列化的类。

@Serializable    
data class Packet(val dataType: String,val payload: Any)

我使用 Java 序列化通过网络发送它。接收者无法知道有效负载的类型,但 Java 反序列化它就好了,然后我使用 when(dataType) 作为查找来正确地将 Any 对象转换为正确的类型。轻轻松松。

但 Kotlinx 序列化(带有 ProtoBuf)是对这种 Any 类型的坚持者,原因对我来说并不明显。我无法为 Any 注册序列化程序。在文档中,他们推荐了一种多态方法,这有点可行,但您必须输入数据包:

data class Packet<out T : Any>(val dataType: String,val payload: T) : SomeBaseClass<T>

但是这有点糟糕,因为它使用内联具体化类型来压低很多代码路径,而且这并不能解决接收端不知道尝试反序列化有效负载的类型而无需查看dataType 字段优先。

这是最糟糕的 catch-22。该框架不会忽略 payload: Any 字段(给出编译错误),我什至无法编写自定义序列化程序,因为在客户序列化程序中定义了 element 类型的 Any(对于描述符)给出了“没有为 Any 注册序列化程序”的相同运行时错误

解决方法

我使用 Java 序列化通过网络发送它。接收器无法知道有效负载的类型,但 Java 反序列化它就好了,然后我使用 when(dataType) 作为查找将 Any 对象正确转换为其正确类型。轻轻松松。

这是因为java序列化相当原始——只有一种方法可以序列化(并因此反序列化)一个对象。在 kotlinx.serialization 中,每个类都可以有自己的序列化策略(甚至几个)。这种灵活性是有代价的。 可以处理 Any 的序列化(针对其子类的声明列表),但在一般情况下,基于部分反序列化对象的 dataType 字段动态确定反序列化策略是不可能的,因为无法保证 { {1}} 字段将首先反序列化。一些序列化格式(如 JSON 或 Protobuf)具有无序模式。可能会发生 dataType 即将在 payload 之前被反序列化,并且 Decoder 接口不允许返回/多次传递。

如果您确定序列化格式/消息中的属性顺序(或者只是觉得很幸运),您可以使用以下自定义序列化程序:

dataType

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。