Json
Модуль Json позволяет создавать производительные и без использования рефлексии читатели и писатели для классов приложения посредствам разметки классов аннотациями.
Подключение¶
Зависимость build.gradle
:
Модуль:
Зависимость build.gradle.kts
:
Модуль:
Запись¶
Можно воспользоваться @JsonWriter
для создания только писателя:
Чтение¶
Можно воспользоваться @JsonReader
для создания только читателя:
Чтение & Запись¶
Можно воспользоваться @Json
для создания сразу читателя и писателя.
В большинстве случаев предпочтительнее использовать именно аннотацию @Json
:
Обязательные поля¶
По умолчанию все поля объявленные в объекте считаются обязательными (NotNull).
По умолчанию все поля объявленные в объекте которые не используют Kotlin Nullability синтаксис считаются обязательными (NotNull).
Необязательное поля¶
В случае если поле в Json является необязательным, то есть может отсутствовать то,
можно использовать аннотацию @Nullable
для соответствия поля в Json и DTO:
- Подойдет любая аннотация
@Nullable
, такие какjavax.annotation.Nullable
/jakarta.annotation.Nullable
/org.jetbrains.annotations.Nullable
/ и т.д.
Предполагается использовать Kotlin Nullability синтаксис и помечать такой параметр как Nullable:
Именование поля¶
В случае если поле в Json называется иначе от того что требуется использовать в классе,
можно использовать аннотацию @JsonField
для соответствия поля в Json и DTO.
Игнорирование поля¶
В случае если поле в DTO не хочется читать/писать,
можно использовать аннотацию @JsonSkip
и проигнорировать такое поле.
Уровни записи¶
Поведение по умолчанию не подразумевает запись полей с null
значениями. (1)
IncludeType.NON_NULL
- включать поле в запись если неnull
В случае если хочется изменить поведение записи в этих моментах то предлагается использовать аннотацию @JsonInclude
.
Аннотацию можно использовать не только над полем, но также над классом и тогда правило будет действовать на все поля сразу.
Доступны различные варианты использования:
IncludeType.ALWAYS
- включать поле в запись всегдаIncludeType.NON_NULL
- включать поле в запись если неnull
IncludeType.NON_EMPTY
- включать поле в запись если это неnull
и не пустая коллекция
Пример использования аннотации:
Указание конструктора¶
В случае если хочется использовать определенный конструктор для сериализации,
то это можно сделать с указанием над конструктором аннотации @JsonReader
либо аннотации которая имеет меньший приоритет @Json
:
JsonNullable обертка¶
В случае если во время десериализации, хочется отличать отсутствующее поле от указанного null
значения,
предполагается использовать специальный тип JsonNullable
, который позволяет отражать все состояния поля после десериализации.
Изолированные классы и интерфейсы¶
В случае если требуется писать различные Json объекты в зависимости от значения в конкретном поле, предполагается использовать изолированный класс/интерфейс для представления таких объектов.
Для поддержки изолированных классов добавлены две аннотации:
@JsonDiscriminatorField
- указывает поле дискриминатора в DTO, которым помечается sealed класс/интерфейс@JsonDiscriminatorValue
- значение для вышеуказанного поля, помечает класс-наследник sealed класса/интерфейса
@Json
@JsonDiscriminatorField("type")
public sealed interface Event {
@JsonDiscriminatorValue("firstType")
record FirstTypeEvent(String id, FirstData data) implements Event {}
@JsonDiscriminatorValue("secondType")
record SecondTypeEvent(String id, SecondData data) implements Event {}
@JsonDiscriminatorValue("thirdType")
record ThirdTypeEvent(String id, ThirdData data) implements Event {}
}
@Json
@JsonDiscriminatorField("type")
sealed interface Event {
@JsonDiscriminatorValue("firstType")
data class FirstTypeEvent(val id: String, data: FirstData) : Event
@JsonDiscriminatorValue("secondType")
data class SecondTypeEvent(val id: String, data: SecondData) : Event
@JsonDiscriminatorValue("thirdType")
data class ThirdTypeEvent(val id: String, data: ThirdData) : Event
}
Для классов-наследников будут созданы JsonReader
и JsonWriter
по тем же правилам, как если бы на них была аннотация @Json
и создастся JsonReader
и JsonWriter
для самого sealed класса/интерфейса.
Json объект ниже будет записан в класс FirstTypeEvent
:
Поддерживаемые типы¶
Модуль предоставляет обширный список поддерживаемых из коробки типов которые покрывают большую часть того что может понадобиться.
Список поддерживаемых типов
- Boolean
- boolean
- Short
- short
- Integer
- int
- Long
- long
- Double
- double
- Float
- float
- byte[]
- String
- UUID
- BigInteger
- BigDecimal
- List
- Set
- LocalDate
- LocalTime
- LocalDateTime
- OffsetTime
- OffsetDateTime
- ZonedDateTime
- Year
- YearMonth
- MonthDay
- Month
- DayOfWeek
- ZoneId
- Duration
Собственные типы¶
В случае если требуется писать/читать собственный тип, то предлагается зарегистрировать собственную фабрику для JsonReader
/ JsonWriter
:
Пример регистрации собственно JsonWriter
:
Jackson¶
В случае если хочется использовать Jackson
для записи/чтения, то можно самому зарегистрировать фабрику
предоставляющую ObjectMapper
и соответствующие Mappers
которые требуются в других Kora модулях будут предоставлены зависимостью ниже:
Зависимость build.gradle
:
annotationProcessor "ru.tinkoff.kora:json-annotation-processor"
implementation "ru.tinkoff.kora:jackson-module"
Модуль:
Зависимость build.gradle.kts
:
Модуль: