JSON with spray-json

spray-json 提供了一种使用 JSON 的简便方法。使用隐式格式,一切都在幕后发生:

使用 SBT 使库可用

要使用 SBT 托管库依赖项管理 spray-json

libraryDependencies += "io.spray" %% "spray-json" % "1.3.2"

请注意,最后一个参数,即版本号(1.3.2),在不同的项目中可能会有所不同。

spray-json 库位于 repo.spray.io

导入库

import spray.json._
import DefaultJsonProtocol._

默认的 JSON 协议 DefaultJsonProtocol 包含所有基本类型的格式。要为自定义类型提供 JSON 功能,请使用便捷构建器来显示格式或写入格式。

阅读 JSON

// generates an intermediate JSON representation (abstract syntax tree)
val res = """{ "foo": "bar" }""".parseJson // JsValue = {"foo":"bar"}

res.convertTo[Map[String, String]] // Map(foo -> bar)

写 JSON

val values = List("a", "b", "c")
values.toJson.prettyPrint // ["a", "b", "c"]

DSL

不支持 DSL。

读写案例类

以下示例显示如何将案例类对象序列化为 JSON 格式。

case class Address(street: String, city: String)
case class Person(name: String, address: Address)

// create the formats and provide them implicitly
implicit val addressFormat = jsonFormat2(Address)
implicit val personFormat = jsonFormat2(Person)

// serialize a Person
Person("Fred", Address("Awesome Street 9", "SuperCity"))
val fredJsonString = fred.toJson.prettyPrint

这会产生以下 JSON:

{
  "name": "Fred",
  "address": {
    "street": "Awesome Street 9",
    "city": "SuperCity"
  }
}

反过来,JSON 可以反序列化为一个对象:

val personRead = fredJsonString.parseJson.convertTo[Person] 
//Person(Fred,Address(Awesome Street 9,SuperCity))

自定义格式

如果需要特殊的类型序列化,请编写自定义 JsonFormat 。例如,如果 Scala 中的字段名称与 JSON 中的字段名称不同。或者,如果基于输入实例化不同的具体类型。

implicit object BetterPersonFormat extends JsonFormat[Person] {
    // deserialization code
    override def read(json: JsValue): Person = {
        val fields = json.asJsObject("Person object expected").fields
        Person(
            name = fields("name").convertTo[String],
            address = fields("home").convertTo[Address]
        )
    }

    // serialization code
    override def write(person: Person): JsValue = JsObject(
        "name" -> person.name.toJson,
        "home" -> person.address.toJson
    )
}