JSON (JavaScript Object Notation) — это текстовый формат для хранения и передачи данных. Он широко используется в веб-приложениях для обмена данными между клиентом и сервером.
kotlinx.serialization — это официальная библиотека Kotlin
для сериализации и десериализации данных.
Она поддерживает различные форматы, включая JSON
, и позволяет легко преобразовывать объекты Kotlin в JSON
и обратно.
- Сериализация - Преобразование объектов
Kotlin
вJSON
. - Десериализация - Преобразование
JSON
в объектыKotlin
. - Аннотации - Упрощают настройку процесса сериализации.
serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
plugins {
alias(libs.plugins.serialization)
}
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinxSerializationJson" }
/**
* Serialization
*
* https://github.com/Kotlin/kotlinx.serialization
* https://kotlinlang.org/docs/serialization.html
*/
implementation(libs.kotlinx.serialization.json)
retrofit2-kotlinx-serialization-converter = { module = "com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter", version.ref = "retrofit2KotlinxSerializationConverter" }
/**
* Retrofit
*
* https://github.com/square/retrofit
* https://square.github.io/retrofit/
*
* https://github.com/JakeWharton/retrofit2-kotlinx-serialization-converter
* https://github.com/square/retrofit/tree/trunk/retrofit-converters/kotlinx-serialization
*/
implementation(libs.retrofit)
implementation(libs.retrofit2.kotlinx.serialization.converter)
Аннотация @Serializable
указывает, что класс может быть сериализован и десериализован.
Аннотация @SerialName
позволяет указать имя поля в JSON, если оно отличается от имени свойства в классе.
/**
* Класс, представляющий пост в приложении.
* Этот класс используется для хранения данных о посте, включая его идентификатор, автора, дату публикации,
* содержание и информацию о лайках.
*
* @property id Уникальный идентификатор поста. По умолчанию 0L.
* @property author Имя автора поста. По умолчанию пустая строка.
* @property authorId Уникальный идентификатор автора поста. По умолчанию 0L.
* @property authorAvatar Ссылка на аватар автора поста. По умолчанию пустая строка.
* @property published Дата и время публикации поста. По умолчанию текущее время.
* @property content Текстовое содержание поста. По умолчанию пустая строка.
* @property likedByMe Флаг, указывающий, лайкнул ли текущий пользователь этот пост. По умолчанию false.
* @property likeOwnerIds Множество идентификаторов пользователей, которые лайкнули этот пост. По умолчанию пустое множество.
* @property attachment Вложение (например, изображение или видео), связанное с постом. По умолчанию null.
*
* @see Attachment
* @see InstantSerializer
*/
@Serializable
data class PostData(
@SerialName("id")
val id: Long = 0L,
@SerialName("author")
val author: String = "",
@SerialName("authorId")
val authorId: Long = 0L,
@SerialName("authorAvatar")
val authorAvatar: String = "",
@SerialName("published")
@Serializable(with = InstantSerializer::class)
val published: Instant = Instant.now(),
@SerialName("content")
val content: String = "",
@SerialName("likedByMe")
val likedByMe: Boolean = false,
@SerialName("likeOwnerIds")
val likeOwnerIds: Set<Long> = emptySet(),
@SerialName("attachment")
val attachment: Attachment? = null,
)
Используйте метод Json.encodeToString
, чтобы преобразовать объект в JSON
-строку.
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
fun main() {
val user = User("Sergey", 18, true)
val json = Json.encodeToString(user)
println(json) // {"name":"Sergey","age":18,"isStudent":true}
}
Используйте метод Json.decodeFromString
, чтобы преобразовать JSON
-строку в объект.
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
fun main() {
val json = """{"name":"Sergey","age":18,"isStudent":true}"""
val user = Json.decodeFromString<User>(json)
println(user) // User(name=Sergey, age=18, isStudent=true)
}
Библиотека kotlinx.serialization
позволяет настраивать процесс сериализации и десериализации с помощью объекта Json
.
/**
* Конфигурация JSON-сериализации.
*
* - `ignoreUnknownKeys = true`: Игнорирует неизвестные ключи в JSON.
* - `coerceInputValues = true`: Приводит значения `null` к значениям по умолчанию.
*/
private val json = Json {
ignoreUnknownKeys = true
coerceInputValues = true
}
val json = Json {
prettyPrint = true // Красивый вывод JSON с отступами
ignoreUnknownKeys = true // Игнорировать неизвестные ключи в JSON
isLenient = true // Разрешить нестрогий формат JSON (например, без кавычек)
}
val user = User("Sergey", 25, true)
val jsonString = json.encodeToString(user)
println(jsonString)
Можно сериализовать и десериализовать вложенные объекты.
@Serializable
data class Address(
val city: String,
val street: String
)
@Serializable
data class User(
val name: String,
val age: Int,
val address: Address
)
fun main() {
val user = User("Sergey", 25, Address("Moscow", "Lenina"))
val json = Json.encodeToString(user)
println(json) // {"name":"Sergey","age":25,"address":{"city":"Moscow","street":"Lenina"}}
}
Библиотека поддерживает сериализацию и десериализацию коллекций (например, списков).
@Serializable
data class User(
val name: String,
val age: Int
)
fun main() {
val users = listOf(
User("Sergey", 25),
User("Anna", 30)
)
val json = Json.encodeToString(users)
println(json) // [{"name":"Sergey","age":25},{"name":"Anna","age":30}]
}
Если свойство может быть null
, нужно использовать nullable-тип
.
@Serializable
data class User(
val name: String,
val age: Int? // Возраст может быть null
)
fun main() {
val json = """{"name":"Sergey"}"""
val user = Json.decodeFromString<User>(json)
println(user) // User(name=Sergey, age=null)
}
Если стандартной сериализации недостаточно, можно создать кастомный сериализатор.
/**
* Сериализатор для класса [Instant].
*
* Этот сериализатор используется для преобразования объектов [Instant] в строку и обратно.
* Он реализует интерфейс [KSerializer] из библиотеки Kotlinx Serialization.
*
* @see KSerializer Интерфейс для создания пользовательских сериализаторов.
* @see Instant Класс, представляющий момент времени.
*/
class InstantSerializer : KSerializer<Instant> {
/**
* Описание сериализации для [Instant].
*
* Это описание указывает, что [Instant] будет сериализован как примитивный тип [PrimitiveKind.STRING].
*/
override val descriptor: SerialDescriptor =
PrimitiveSerialDescriptor("Instant", PrimitiveKind.STRING)
/**
* Метод для десериализации строки в объект [Instant].
*
* @param decoder Декодер, используемый для чтения данных.
* @return Объект [Instant], полученный из строки.
*/
override fun deserialize(decoder: Decoder): Instant =
Instant.parse(decoder.decodeString())
/**
* Метод для сериализации объекта [Instant] в строку.
*
* @param encoder Энкодер, используемый для записи данных.
* @param value Объект [Instant], который нужно сериализовать.
*/
override fun serialize(encoder: Encoder, value: Instant) =
encoder.encodeString(value.toString())
}
JSON — Текстовый формат для хранения и передачи данных.
kotlinx.serialization — Библиотека для сериализации и десериализации в Kotlin.
-
@Serializable — Для сериализуемых классов.
-
@SerialName — Для указания имени поля в JSON.
-
Сериализация -
Json.encodeToString
. -
Десериализация -
Json.decodeFromString
. -
Настройка JSON - использование объекта
Json
для настройки. -
Вложенные объекты и коллекции - Поддерживаются автоматически.
-
Кастомные сериализаторы - Для нестандартных типов данных.