@SerialInfo - Как управлять пользовательскими последовательными аннотациями с сериализацией Kotlinx?
Документация по сериализации Kotlinx
Согласно с Kotlinx.serialization
определяемые пользователем аннотаций документ:
"В процессе сериализации / десериализации ваш собственный класс аннотации доступен в
SerialDescriptor
объект ":
override fun encodeElement(desc: SerialDescriptor, index: Int): Boolean {
val annotations = desc.getElementAnnotations(index)
...
}
Что я хочу сделать
мне нужно @Transient
эквивалентно, но условно:
- классический способ, где:
Json.stringify(serializer, myClass)
работает как обычно. - пользовательский способ, где:
Json.stringify(customSerializer, myClass)
вернет обычный 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
. Где я могу получить доступ к ElementValueEncoder в настраиваемом сериализаторе?
Я также нашел этот образец демонстрации в репозитории github kotlinx.serialization. Он используетTaggedEncoder
& TaggedDecoder
где я могу отменить encodeTaggedValue
. Но и здесь я не знаю, как использовать этот кодировщик / декодер в процессе сериализации / десериализации.
в заключение
Где я могу отменить fun encodeElement(desc: SerialDescriptor, index: Int): Boolean
, и как я могу обрабатывать свою собственную аннотацию сериализации?
Спасибо!!
1 ответ
Прежде всего, вам нужно понять разницу между сериализатором и кодировщиком. Сериализатор (представленныйKSerializer
) определяет, как выглядит ваш класс, а Encoder (представленный, например, JsonOutput
) определяет, как данные будут записываться. Вы можете найти дополнительную информацию по этой теме здесь: https://github.com/Kotlin/KEEP/blob/master/proposals/extensions/serialization.md.
Таким образом, функция настраиваемых аннотаций в основном используется для предоставления информации о формате для Encoder. Типичное использование такой аннотации:ProtoId
- идентификатор свойства, специфичный для формата protobuf, который должен распознаваться ProtobufEncoder
. Такие аннотации обычно определяются авторами формата вместе с их кодировщиками.
Как я вижу, вы хотите использовать уже существующий кодировщик (формат JSON), поэтому переопределите encodeElement
невозможно, поскольку кодировщики Json не могут быть разделены на подклассы. Я бы посоветовал вам использовать собственный сериализатор json transofrming для достижения вашей цели. К сожалению, в настоящее время kotlinx.serialization не имеет механизма для обобщения такого преобразования, поэтому вам необходимо написать такой сериализатор для каждого класса.