Разбор JSON
Преобразуйте текст в значения JSON.
«Разбор JSON» — бесплатный урок Scala for Backend Engineering & Functional Programming на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Scala for Backend Engineering & Functional Programming, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Scala for Backend Engineering & Functional Programming содержит 4 уроков всего.
Зачем нужен Circe?
Circe — популярная библиотека JSON для Scala, построенная на функциональной экосистеме cats.
Она отдаёт предпочтение типобезопасности и неизменяемости: синтаксический разбор возвращает Either, а не выбрасывает исключение, а декодирование создаёт типизированные значения вместо нетипизированных отображений.
В этом уроке рассматривается преобразование необработанного текста JSON в модель Json библиотеки Circe.
Добавление зависимости
Circe поставляется в виде нескольких модулей. Для разбора и основной модели нужны circe-core и circe-parser.
Модуль circe-generic добавляет автоматический вывод кодеков, который рассматривается в следующих уроках.
libraryDependencies ++= Seq(
"io.circe" %% "circe-core" % "0.14.6",
"io.circe" %% "circe-parser" % "0.14.6"
)Функция parse
Точка входа для чтения JSON — io.circe.parser.parse.
Она принимает String и возвращает Either[ParsingFailure, Json]. Левая сторона содержит синтаксические ошибки, а правая — разобранное дерево.
import io.circe.parser._
val result = parse("{\"name\": \"Ada\", \"age\": 36}")
// result: Either[ParsingFailure, Json]Обработка ошибок разбора
Поскольку parse возвращает Either, Вы обрабатываете ошибки явно с помощью сопоставления с образцом или комбинаторов, а не через try/catch.
ParsingFailure содержит понятное человеку сообщение с описанием синтаксической проблемы.
parse("{ not valid }") match {
case Right(json) => println(json)
case Left(err) => println(s"Failed: ${err.message}")
}Модель Json
Успешно разобранное значение — это Json, неизменяемое дерево, представляющее один из шести типов JSON: объект, массив, строку, число, логическое значение или null.
Вы можете исследовать его с помощью предикатов, таких как isObject, или свернуть дерево в зависимости от его формы.
val json = parse("[1, 2, 3]").getOrElse(Json.Null)
println(json.isArray) // true
println(json.isObject) // falseНавигация с помощью курсора
Чтобы читать вложенные данные, вызовите .hcursor для значения Json. HCursor — это зиппер, позволяющий перемещаться по дереву.
Используйте downField, чтобы перейти к ключу объекта.
val json = parse("{\"user\": {\"name\": \"Ada\"}}").toOption.get
val cursor = json.hcursor
val name = cursor.downField("user").downField("name").as[String]
// name: Either[DecodingFailure, String] = Right(Ada)Извлечение значений с помощью as
После позиционирования .as[A] пытается декодировать выбранное значение в тип A.
Он возвращает Either[DecodingFailure, A], поэтому несоответствие типов представляется как значение, а не как исключение.
val json = parse("{\"age\": 36}").toOption.get
val age = json.hcursor.downField("age").as[Int]
println(age) // Right(36)parse и decode
Используйте parse, если хотите вручную исследовать необработанное дерево Json.
Используйте decode[A], если хотите за один шаг перейти от String к типизированному значению A. Эта операция объединяет разбор и декодирование.
import io.circe.parser.decode
val n: Either[io.circe.Error, Int] =
decode[Int]("42")
println(n) // Right(42)Необязательные поля
В реальном JSON ключи часто отсутствуют. Метод курсора get[A] для указанного поля завершается ошибкой, если поле отсутствует, а getOrElse подставляет значение по умолчанию.
Декодирование в Option[A] трактует отсутствующее поле или поле со значением null как None.
val json = parse("{\"name\": \"Ada\"}").toOption.get
val nick = json.hcursor.get[Option[String]]("nickname")
println(nick) // Right(None)Разбор массивов
Вы можете напрямую декодировать массив JSON в коллекцию Scala, запросив List[A] или Vector[A].
Circe преобразует каждый элемент и прекращает обработку с ошибкой DecodingFailure, если тип какого-либо элемента неверен.
import io.circe.parser.decode
val xs = decode[List[Int]]("[1, 2, 3]")
println(xs) // Right(List(1, 2, 3))Форматированный вывод
Любое значение Json можно снова вывести в текст с помощью .noSpaces для компактного вывода или .spaces2 для вывода с отступами.
Это позволяет преобразовать разобранные данные обратно и удобно для журналирования или отладки.
val json = parse("{\"a\":1,\"b\":2}").toOption.get
println(json.noSpaces)
println(json.spaces2)Быстрая проверка
Проверьте, насколько хорошо Вы поняли разбор Circe.
Итоги
Вы научились преобразовывать текст JSON в модель Circe. parse возвращает Either[ParsingFailure, Json], а decode[A] сразу создаёт типизированное значение.
HCursor перемещается с помощью downField, а .as[A] извлекает типизированные значения. Ошибки представлены значениями, а не исключениями.
Часто задаваемые вопросы
Урок «Разбор JSON» бесплатный?
Да — полный текст урока «Разбор JSON» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Scala for Backend Engineering & Functional Programming, подпишись на CoddyKit PRO. Курс Scala for Backend Engineering & Functional Programming содержит 4 уроков всего.
Чему я научусь в уроке «Разбор JSON»?
Преобразуйте текст в значения JSON. Ты практикуешь Scala for Backend Engineering & Functional Programming с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Scala for Backend Engineering & Functional Programming?
Предыдущий опыт не требуется. Scala for Backend Engineering & Functional Programming на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.
Сколько времени занимает урок «Разбор JSON»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Scala for Backend Engineering & Functional Programming?
Да. Каждый урок Scala for Backend Engineering & Functional Programming включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.