@SerialInfo - 如何使用 Kotlinx 序列化管理用户定义的串行注释?
Posted
技术标签:
【中文标题】@SerialInfo - 如何使用 Kotlinx 序列化管理用户定义的串行注释?【英文标题】:@SerialInfo - How to manage user-defined serial annotations with Kotlinx serialization? 【发布时间】:2020-06-11 17:35:07 【问题描述】:Kotlinx 序列化文档
根据Kotlinx.serialization
用户自定义注解doc:
“在一个序列化/反序列化的过程中,你自己的注解类在
SerialDescriptor
对象中可用”:
override fun encodeElement(desc: SerialDescriptor, index: Int): Boolean
val annotations = desc.getElementAnnotations(index)
...
我想做什么
我需要一个 @Transient
等效项,但有条件:
Json.stringify(serializer, myClass)
照常工作。
自定义方式 where : Json.stringify(customSerializer, myClass)
将返回通常的 json 但排除所有 @MyAnnotation
-tagged 值。
这是我的代码
@SerialInfo
@Target(AnnotationTarget.PROPERTY)
annotation class CustomAnnotation
@Serializable
data class MyClass(val a: String, @CustomAnnotation val b: Int = -1)
我想构建一个自定义序列化程序并实现类似
override fun encodeElement(desc: SerialDescriptor, index: Int): Boolean
val isTaggedAsCustomAnnotation = desc.getElementAnnotations(index).any it is CustomAnnotation
val myCondition = mySerializer.getMyConditionBlablabla
if(myCondition && isTaggedAsCustomAnnotation)
encode()
...
我发现了什么
abstract class ElementValueEncoder : Encoder, CompositeEncoder
...
open fun encodeElement(desc: SerialDescriptor, index: Int): Boolean = true
但我不知道如何构建自定义序列化程序,以便我可以覆盖该函数Encoder.encodeElement
。我可以在哪里访问自定义 Serializer 中的 ElementValueEncoder ?
我还在 kotlinx.serialization github 存储库中找到了这个 sample demo。它使用TaggedEncoder
和TaggedDecoder
我可以覆盖encodeTaggedValue
。但是在这里我不知道如何在序列化/反序列化过程中使用这些编码器/解码器。
终于
在哪里可以覆盖fun encodeElement(desc: SerialDescriptor, index: Int): Boolean
,以及如何处理我自己定义的序列化注释?
谢谢!!
【问题讨论】:
【参考方案1】:首先要掌握Serializer和Encoder的区别。序列化器(由KSerializer
表示)定义您的类的外观,编码器(由例如JsonOutput
表示)定义如何记录数据。您可以在此处找到有关该主题的更多信息:https://github.com/Kotlin/KEEP/blob/master/proposals/extensions/serialization.md#core-api-overview-and-mental-model。
因此,自定义注释功能主要用于向编码器提供格式特定信息。这种注解的典型用法是ProtoId
——属性id,特定于protobuf格式,应该被ProtobufEncoder
识别。此类注释通常由格式作者连同其编码器一起定义。
正如我所见,您在这里要做的是使用已经存在的编码器(JSON 格式),因此无法覆盖 encodeElement
,因为无法对 Json 编码器进行子类化。我建议您使用custom json transofrming serializer 来实现您的目标。不幸的是,目前 kotlinx.serialization 没有机制来泛化这种转换,因此您需要为每个类编写这样的序列化器。
【讨论】:
以上是关于@SerialInfo - 如何使用 Kotlinx 序列化管理用户定义的串行注释?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Kotlin 中使用 ViewModelProviders