Scala 如何使用jsonspray序列化具有traits的case类

Scala 如何使用jsonspray序列化具有traits的case类,scala,spray,spray-json,Scala,Spray,Spray Json,我理解,如果我有: case class Person(name: String) 我可以用 object PersonJsonImplicits extends DefaultJsonProtocol { implicit val impPerson = jsonFormat1(Person) } 并将其序列化为: import com.example.PersonJsonImplicits._ import spray.json._ new Person("somename").to

我理解,如果我有:

case class Person(name: String)
我可以用

object PersonJsonImplicits extends DefaultJsonProtocol {
  implicit val impPerson = jsonFormat1(Person)
}
并将其序列化为:

import com.example.PersonJsonImplicits._
import spray.json._
new Person("somename").toJson
但是如果我有呢

trait Animal
case class Person(name: String) extends Animal
我的代码里有个地方

val animal = ???
我需要序列化它,我想使用json

我应该添加哪个序列化程序我希望有如下内容:

object AnimalJsonImplicits extends DefaultJsonProtocol {
  implicit val impAnimal = jsonFormat???(Animal)
}
也许我需要添加一些匹配器,以便检查动物是什么类型的,这样如果它是人,我会将它指向人,但什么也找不到。。。我在看书,不知道怎么做

那么,如何序列化

trait Animal
case class Person(name: String) extends Animal

使用json spray?

您有几个选项:

选择1 扩展
RootJsonFormat[Animal]
,并放置自定义逻辑以匹配不同类型的
Animal

import spray.json._
import DefaultJsonProtocol._

trait Animal   
case class Person(name: String, kind: String = "person") extends Animal

implicit val personFormat = jsonFormat2(Person.apply)   
implicit object AnimalJsonFormat extends RootJsonFormat[Animal] {
  def write(a: Animal) = a match {
    case p: Person => p.toJson
  }
  def read(value: JsValue) = 
    // If you need to read, you will need something in the 
    // JSON that will tell you which subclass to use
    value.asJsObject.fields("kind") match {
      case JsString("person") => value.convertTo[Person]
    }
}

val a: Animal = Person("Bob")
val j = a.toJson
val a2 = j.convertTo[Animal]
如果将此代码粘贴到Scala REPL中,则会得到以下输出:

a: Animal = Person(Bob,person)
j: spray.json.JsValue = {"name":"Bob","kind":"person"}
a2: Animal = Person(Bob,person)

选择2 另一种选择是为
Person
Animal
的任何其他子类提供隐式
jsonFormat
s,然后像这样编写序列化代码:

def write(a: Animal) = a match {
  case p: Person => p.toJson
  case c: Cat => c.toJson
  case d: Dog => d.toJson
}

可以通过扩展
RootJsonFormat
来完成。一个例子可以从中找到

特征动物“{”是missing@MikhailZaretsky-在不需要时省略trait和类主体是有效的Scala语法。此代码可编译,不需要“{”。如果您未绑定到JSON spray,则可以使用它自动处理此情况。