4

我试图在这里找到一些帮助,将 DefaultJsonProtocol 的 JsonFormat 扩展应用于包含对象序列的类。

所以对于课程:

class Person(val name: String, [......], val adresses: Seq[Adress])
class Adress(val streetname: String, val plz: BigDecimal, val city: String)

现在我想应用我的 JsonFormat:

object PersonJsonProtocol extends DefaultJsonProtocol {
  implicit object PersonJsonFormat extends RootJsonFormat[Person] {
    def write(pers: Person) = JsObject(
    "name" -> JsString(pers.name),
    [......],
    "adresses" -> JsArray(pers.adresses)
)
def read(value: JsValue) = {...}
}

但实际上我不知道该怎么做。我搜索了 spray-json 文档并通过 google、stackoverflow & Co. 进行了搜索。我对 Scala/Spray 完全陌生,也许我只是错过了重点。所以,也许这里有人好心帮助我。没有地址序列我会工作。

使用示例中提供的 JsArray,我得到类型不匹配。它正在检查 List[JsValue] 但也转换为列表不匹配仍然存在。

我还尝试插入一个单独的 AdressJsonProtocol 并通过以下方式包含它:“addresses”-> AdressJsonFormat.write(pers.adresses) 但它又是一个序列...

4

2 回答 2

9

You don't need to write a DefaultJsonProtocol for each case class, except if you want some special logic (formatting, filtering ...)

Have you tried to simply use the default case class serialization?

implicit val formatPerson = jsonFormat6(Adress)
implicit val formatAddress = jsonFormat3(Adress)

The number in jsonFormat'number' stands for the number of members in your case class.

Then spray-json will take care of your nested Address collection when serializing a Person.

于 2014-02-13T17:09:45.790 回答
3

看源码spray.json.CollectionFormats

这是一个可运行的实现:

import spray.json._

class Adress(val streetname: String, val plz: BigDecimal, val city: String)

class Person(val name: String, val adresses: Seq[Adress])

object PersonJsonProtocol extends DefaultJsonProtocol {
  implicit object AdressJsonFormat extends RootJsonFormat[Adress] {
    def write(addr: Adress) = JsObject(Map(
      "streetname" -> JsString(addr.streetname),
      "plz" -> JsNumber(addr.plz),
      "city" -> JsString(addr.city)
    ))
    def read(value: JsValue): Adress = ???
  }
  implicit object PersonJsonFormat extends RootJsonFormat[Person] {
    def write(pers: Person) = JsObject(Map(
      "name" -> JsString(pers.name),
      "adresses" -> JsArray(pers.adresses.map(_.toJson).toList)
    ))
    def read(value: JsValue): Person = ???
  }
}

object Main extends App {
  import PersonJsonProtocol._
  val person = new Person("joe", Seq(new Adress("street", 123, "city")))
  println("poso's default toString: %s".format(person))
  val personJVal = person.toJson
  println("JValue's toString: %s".format(personJVal))
  val personJson = personJVal.prettyPrint
  println("pretty-printing: %s".format(personJson))
}

产生:

poso's default toString: Person@680ccad
JValue's toString: {"name":"joe","adresses":[{"streetname":"street","plz":123,"city":"city"}]}
pretty-printing: {
  "name": "joe",
  "adresses": [{
    "streetname": "street",
    "plz": 123,
    "city": "city"
  }]
}
于 2014-02-13T18:18:30.600 回答