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
    )
}