@SerialInfo-如何使用Kotlinx序列化管理用户定义的串行注释? Kotlinx序列化文档
根据@SerialInfo-如何使用Kotlinx序列化管理用户定义的串行注释? Kotlinx序列化文档,kotlin,serialization,annotations,kotlinx.serialization,Kotlin,Serialization,Annotations,Kotlinx.serialization,根据Kotlinx.serialization用户定义的注释: “在序列化/反序列化过程中,SerialDescriptorobject中提供了您自己的注释类:” 我想做什么 我需要一个@Transient等价物,但有条件: 经典的方式:Json.stringify(serializer,myClass)照常工作 自定义方式,其中:Json.stringify(customSerializer,myClass)将返回通常的Json,但会将所有的@MyAnnotation-标记的值进行转换 这
Kotlinx.serialization
用户定义的注释:
“在序列化/反序列化过程中,SerialDescriptor
object中提供了您自己的注释类:”
我想做什么
我需要一个@Transient
等价物,但有条件:
- 经典的方式:
照常工作李>Json.stringify(serializer,myClass)
- 自定义方式,其中:
将返回通常的Json,但会将所有的Json.stringify(customSerializer,myClass)
-标记的值进行转换@MyAnnotation
@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()
}
...
}
我发现了什么
但我不知道如何构建自定义序列化程序,以便覆盖该函数Encoder.encodeElement
。在哪里可以访问自定义序列化程序中的ElementValueEncoder
我在kotlinx.github repo中也找到了这个。它使用的是TaggedEncoder
&TaggedDecoder
,我可以覆盖encodeTaggedValue
。但在这里,我不知道如何在序列化/反序列化过程中使用这些编码器/解码器
最后
我可以在哪里重写元素(desc:SerialDescriptor,index:Int):Boolean,以及如何处理自己定义的序列化注释
谢谢 首先,您需要掌握序列化程序和编码器之间的区别。序列化器(由
KSerializer
表示)定义类的外观,编码器(由JsonOutput
表示)定义数据的记录方式。您可以在此处找到有关该主题的更多信息:
所以,自定义注释功能主要用于向编码器提供特定于格式的信息。这种注释的典型用法是ProtoId
–protobuf格式特有的属性id,应该由ProtobufEncoder
识别。这种注释通常由格式作者及其编码器一起定义
正如我所看到的,您想在这里做的是使用已经存在的编码器(JSON格式),因此重写encodeElement
是不可能的,因为JSON编码器不能被子类化。我建议你用它来实现你的目标。不幸的是,目前kotlinx.serialization没有泛化这种转换的机制,所以您需要为每个类编写这样的序列化程序
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
}