0Pricing
Scala for Backend Engineering & Functional Programming · 课时

解析 JSON

将文本转换为 JSON 值。

解析 JSON 是 CoddyKit 上的免费 Scala for Backend Engineering & Functional Programming 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Scala for Backend Engineering & Functional Programming 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Scala for Backend Engineering & Functional Programming 课程共包含 4 节课。

为什么选择 Circe?

Circe 是 Scala 中广受欢迎的 JSON 库,构建于 cats 函数式生态之上。

它注重类型安全和不可变性:解析会返回 Either,而不是抛出异常;解码会生成有类型的值,而不是无类型的映射。

本课将介绍如何把原始 JSON 文本转换为 Circe 的 Json 模型。

添加依赖

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

使用游标导航

要读取嵌套数据,请对 Json 值调用 .hcursor。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

如果您希望手动检查原始的 Json 树,请使用 parse。

如果您希望一步将 String 直接转换为有类型的值 A,请使用 decode[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)

解析数组

通过请求 List[A] 或 Vector[A],您可以将 JSON 数组直接解码为 Scala 集合。

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」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Scala for Backend Engineering & Functional Programming 课程的其余内容,请升级到 CoddyKit PRO。 Scala for Backend Engineering & Functional Programming 课程共包含 4 节课。

「解析 JSON」这节课中我会学到什么?

将文本转换为 JSON 值。 你通过在浏览器中直接运行的动手代码来练习 Scala for Backend Engineering & Functional Programming,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Scala for Backend Engineering & Functional Programming 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Scala for Backend Engineering & Functional Programming 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。

「解析 JSON」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Scala for Backend Engineering & Functional Programming 课中编写并运行代码吗?

能。每节 Scala for Backend Engineering & Functional Programming 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 解析 JSON
  2. 解码为样例类
  3. 编码为 JSON
  4. 自定义编解码器
← 返回 Scala for Backend Engineering & Functional Programming