Работа с JSON в Kotlin: парсинг и сериализация для начинающих

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Введение: зачем 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}

5. Работа

Блоги

Рекомендаций по книгам