Введение: почему JSON в Kotlin — это боль и радость одновременно
Если вы когда-нибудь писали под Android или бекенд на Kotlin, вы наверняка сталкивались с JSON. Это как воздух для современного разработчика: API, конфиги, базы данных — всё говорит на этом языке. Но вот парадокс: вопрос "How to parse JSON in Kotlin?" на Stack Overflow набирает тысячи просмотров каждый месяц. Почему? Потому что в Kotlin, в отличие от Java, есть null safety, и старые библиотеки типа Gson начинают "чудить".
В этом туториале мы разберём парсинг JSON в Kotlin от простого к сложному. Вы узнаете, как работать с Kotlinx Serialization, Moshi и классическим Gson. Мы напишем реальный код, который можно сразу скопировать в проект. Поехали!
Что такое JSON и почему Kotlin с ним дружит не сразу?
JSON (JavaScript Object Notation) — это текстовый формат обмена данными. Выглядит он примерно так:
{
"name": "Kotlin",
"year": 2011,
"features": ["null safety", "coroutines"]
}
Казалось бы, что может пойти не так? Но в Kotlin есть строгая типизация и null safety. Когда вы парсите JSON, вы должны явно указать, какие поля могут быть null, а какие — обязательны. Если библиотека этого не учитывает, вы получите NullPointerException или странные баги.
Именно поэтому выбор правильной библиотеки для парсинга JSON в Kotlin — это не просто "либа на вкус", а вопрос стабильности проекта.
Топ-3 библиотеки для парсинга JSON в Kotlin
Мы рассмотрим три основных подхода. Каждый имеет свои плюсы и минусы.
- Kotlinx Serialization — официальная библиотека от JetBrains. Лучшая интеграция с языком.
- Moshi — современная библиотека от Square. Работает и с Java, и с Kotlin.
- Gson — старый добрый стандарт. Всё ещё популярен, но требует осторожности с Kotlin.
1. Kotlinx Serialization — выбор профи
Это нативная библиотека для Kotlin. Она использует кодогенерацию и полностью поддерживает null safety. Если вы пишете новый проект на Kotlin, это ваш выбор.
Установка: Добавьте плагин в build.gradle.kts:
plugins {
kotlin("plugin.serialization") version "1.9.0"
}
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.0")
}
Пример кода:
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
@Serializable
data class User(
val name: String,
val year: Int,
val features: List<String>
)
fun main() {
val jsonString = """
{
"name": "Kotlin",
"year": 2011,
"features": ["null safety", "coroutines"]
}
""".trimIndent()
val user = Json.decodeFromString<User>(jsonString)
println(user.name) // Kotlin
println(user.features[0]) // null safety
}
Обратите внимание: Kotlinx Serialization автоматически подхватывает типы. Если поле в JSON отсутствует, а в data class оно не помечено как nullable, вы получите исключение. Это хорошо — вы не пропустите ошибку.
2. Moshi — гибкий и быстрый
Moshi — это библиотека от Square, которая создавалась с учётом Kotlin. Она также поддерживает кодогенерацию и null safety. В отличие от Gson, Moshi не использует рефлексию по умолчанию, что делает её быстрее.
Установка:
dependencies {
implementation("com.squareup.moshi:moshi-kotlin:1.15.0")
ksp("com.squareup.moshi:moshi-kotlin-codegen:1.15.0")
}
Пример кода:
import com.squareup.moshi.Moshi
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
data class User(val name: String, val year: Int, val features: List<String>)
fun main() {
val moshi = Moshi.Builder()
.addLast(KotlinJsonAdapterFactory())
.build()
val adapter = moshi.adapter(User::class.java)
val jsonString = """{"name":"Kotlin","year":2011,"features":["null safety"]}"""
val user = adapter.fromJson(jsonString)
println(user?.name)
}
Moshi хорош тем, что легко интегрируется с Retrofit и OkHttp. Если вы пишете Android-приложение, это отличный выбор для парсинга JSON в Kotlin.
3. Gson — классика, но с подводными камнями
Gson от Google — самая популярная библиотека для Java. Но в Kotlin она требует дополнительных настроек. Проблема в том, что Gson использует рефлексию и не всегда корректно обрабатывает null safety и data class.
Установка:
dependencies {
implementation("com.google.code.gson:gson:2.10.1")
}
Пример кода:
import com.google.gson.Gson
data class User(val name: String, val year: Int, val features: List<String>)
fun main() {
val gson = Gson()
val jsonString = """{"name":"Kotlin","year":2011,"features":["null safety"]}"""
val user = gson.fromJson(jsonString, User::class.java)
println(user.name)
}
Внимание! Если в JSON будет поле "age": null, а в data class поле age: Int (не nullable), Gson просто проигнорирует это и поставит значение по умолчанию (0). Это может привести к трудноотловимым багам. Поэтому для Kotlin Gson стоит использовать только с осторожностью и явными аннотациями.
Сравнение: что выбрать для вашего проекта?
Вот краткая таблица, которая поможет вам принять решение:
- Kotlinx Serialization — для чистого Kotlin (Android, KMP, Ktor). Лучшая поддержка языка.
- Moshi — для гибридных проектов (Java + Kotlin) или если используете Retrofit.
- Gson — для legacy-проектов или если вы точно знаете, что делаете.
Лично я рекомендую начинать с Kotlinx Serialization. Это современно, безопасно и не требует лишних зависимостей.
Продвинутые техники: работа с API и вложенными объектами
В реальных проектах JSON редко бывает плоским. Часто вы получаете ответ от API с вложенными объектами и массивами. Давайте разберём, как это парсить.