Введение: зачем Kotlin умеет работать с JSON?
JSON (JavaScript Object Notation) — это лёгкий формат обмена данными, который стал стандартом для современных веб-приложений и API. Если вы пишете на Kotlin, будь то Android-приложение или серверная часть, рано или поздно вам придётся парсить JSON-ответы от сервера или сериализовать свои объекты для отправки.
Kotlin — это современный язык, который работает поверх JVM и полностью совместим с Java. Однако у Kotlin есть свои мощные инструменты для работы с JSON, которые делают код более лаконичным и безопасным. В этой статье мы разберём два самых популярных подхода: использование официальной библиотеки kotlinx.serialization и проверенного временем Gson.
Статья рассчитана на начинающих. Мы начнём с простого парсинга строки, затем перейдём к созданию сложных вложенных структур, а в конце затронем сериализацию — превращение ваших объектов обратно в JSON.
1. Подготовка проекта: зависимости и импорты
Прежде чем писать код, нужно добавить библиотеки. Мы рассмотрим два варианта.
1.1. Установка kotlinx.serialization
Это официальное решение от JetBrains. Добавьте в файл build.gradle.kts:
plugins {
kotlin("jvm") version "1.9.0"
kotlin("plugin.serialization") version "1.9.0"
}
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.0")
}
1.2. Установка Gson
Gson — библиотека от Google. Она проще в настройке, но требует больше ручной работы:
dependencies {
implementation("com.google.code.gson:gson:2.10.1")
}
После синхронизации проекта можно писать код.
2. Парсинг JSON в Kotlin с помощью kotlinx.serialization
Этот подход — самый «котлиновский». Вы объявляете data-классы и добавляете аннотацию @Serializable. Библиотека сама сгенерирует код для парсинга.
2.1. Простой пример: данные пользователя
Допустим, у нас есть JSON-строка:
{
"name": "Анна",
"age": 25,
"email": "anna@example.com"
}
Создаём модель:
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
@Serializable
data class User(
val name: String,
val age: Int,
val email: String
)
fun main() {
val jsonString = """
{
"name": "Анна",
"age": 25,
"email": "anna@example.com"
}
""".trimIndent()
val user = Json.decodeFromString<User>(jsonString)
println("Имя: ${user.name}, Возраст: ${user.age}")
}
Как видите, никаких ручных маппингов — всё автоматически.
2.2. Работа со списками и вложенными объектами
Реальные API часто возвращают массивы. Добавим поле address:
@Serializable
data class Address(
val city: String,
val street: String
)
@Serializable
data class UserWithAddress(
val name: String,
val age: Int,
val address: Address
)
fun main() {
val jsonArray = """
[
{"name": "Иван", "age": 30, "address": {"city": "Москва", "street": "Тверская"}},
{"name": "Мария", "age": 22, "address": {"city": "СПб", "street": "Невский"}}
]
""".trimIndent()
val users = Json.decodeFromString<List<UserWithAddress>>(jsonArray)
users.forEach { println("${it.name} живёт в ${it.address.city}") }
}
Обратите внимание: для работы со списками используется generic List<UserWithAddress>.
3. Парсинг JSON с помощью Gson
Gson — это классическая Java-библиотека. Она также отлично работает в Kotlin, но требует чуть больше кода.
3.1. Базовый парсинг
import com.google.gson.Gson
data class Product(
val id: Int,
val title: String,
val price: Double
)
fun main() {
val json = """{"id": 1, "title": "Книга", "price": 599.99}"""
val product = Gson().fromJson(json, Product::class.java)
println("Товар: ${product.title}, Цена: ${product.price}")
}
Обратите внимание: fromJson принимает Class, а не reified тип, поэтому нужно писать Product::class.java.
3.2. Парсинг списка объектов
Для списков в Gson нужно использовать TypeToken:
import com.google.gson.reflect.TypeToken
val jsonList = """[{"id":1,"title":"A"}, {"id":2,"title":"B"}]"""
val listType = object : TypeToken<List<Product>>() {}.type
val products: List<Product> = Gson().fromJson(jsonList, listType)
products.forEach { println(it.title) }
Этот синтаксис громоздкий, поэтому многие Kotlin-разработчики предпочитают kotlinx.serialization.
4. Сериализация: превращаем объекты в JSON
Сериализация — обратный процесс. Вы создаёте объект и превращаете его в строку JSON для отправки на сервер или сохранения в файл.
4.1. Сериализация с kotlinx.serialization
Всё просто — используем Json.encodeToString():
val user = User("Пётр", 28, "petr@mail.com")
val jsonString = Json.encodeToString(user)
println(jsonString)
// Вывод: {"name":"Пётр","age":28,"email":"petr@mail.com"}
4.2. Сериализация с Gson
У Gson тоже есть симметричный метод toJson():
val product = Product(2, "Ноутбук", 89999.99)
val json = Gson().toJson(product)
println(json)
// Вывод: {"id":2,"title":"Ноутбук","price":89999.99}