@SerialInfo - 如何使用 Kotlinx 序列化管理用户定义的序列注释?
@SerialInfo - How to manage user-defined serial annotations with Kotlinx serialization?
Kotlinx 序列化文档
根据Kotlinx.serialization
用户定义的注解doc:
"Inside a process of serialization/deserialization, your own annotation class are available in SerialDescriptor
object" :
override fun encodeElement(desc: SerialDescriptor, index: Int): Boolean {
val annotations = desc.getElementAnnotations(index)
...
}
我想做什么
我需要一个 @Transient
等效项,但有条件:
- 经典方式,其中:
Json.stringify(serializer, myClass)
照常工作。
- 自定义方式,其中:
Json.stringify(customSerializer, myClass)
将 return 通常 json 但排除所有 @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()
}
...
}
我发现了什么
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
。但是我又一次不知道如何在 serialization/deserialization 的过程中使用那些 encoder/decoder。
终于
在哪里可以覆盖 fun encodeElement(desc: SerialDescriptor, index: Int): Boolean
,以及如何处理我自己定义的序列化注释?
谢谢!!
首先,你需要掌握Serializer和Encoder的区别。 Serializer(由 KSerializer
表示)定义了您的 class 的样子,而 Encoder(由例如 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 编码器不能被 subclassed。我建议您使用 custom json transofrming serializer 来实现您的目标。不幸的是,目前 kotlinx.serialization 没有机制来概括这种转换,所以你需要为每个 class.
编写这样的序列化程序
Kotlinx 序列化文档
根据Kotlinx.serialization
用户定义的注解doc:
"Inside a process of serialization/deserialization, your own annotation class are available in
SerialDescriptor
object" :
override fun encodeElement(desc: SerialDescriptor, index: Int): Boolean {
val annotations = desc.getElementAnnotations(index)
...
}
我想做什么
我需要一个 @Transient
等效项,但有条件:
- 经典方式,其中:
Json.stringify(serializer, myClass)
照常工作。 - 自定义方式,其中:
Json.stringify(customSerializer, myClass)
将 return 通常 json 但排除所有@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()
}
...
}
我发现了什么
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
。但是我又一次不知道如何在 serialization/deserialization 的过程中使用那些 encoder/decoder。
终于
在哪里可以覆盖 fun encodeElement(desc: SerialDescriptor, index: Int): Boolean
,以及如何处理我自己定义的序列化注释?
谢谢!!
首先,你需要掌握Serializer和Encoder的区别。 Serializer(由 KSerializer
表示)定义了您的 class 的样子,而 Encoder(由例如 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 编码器不能被 subclassed。我建议您使用 custom json transofrming serializer 来实现您的目标。不幸的是,目前 kotlinx.serialization 没有机制来概括这种转换,所以你需要为每个 class.