how to serialize case classes with traits with jsonspray
scala, spray, spray-json
Solution
You have a couple options:
Option 1
Extend `RootJsonFormat[Animal]` and put your custom logic for matching different types of `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]
If you paste this code into the Scala REPL you get this output:
a: Animal = Person(Bob,person)
j: spray.json.JsValue = {"name":"Bob","kind":"person"}
a2: Animal = Person(Bob,person)
Source
Option 2
Another option is to supply implicit `jsonFormat`s for `Person` and any other subclasses of `Animal` and then write your serialize code like so:
def write(a: Animal) = a match {
case p: Person => p.toJson
case c: Cat => c.toJson
case d: Dog => d.toJson
}
Source
Problem
I understand that if I have: ``` case class Person(name: String) ``` I can use ``` object PersonJsonImplicits extends DefaultJsonProtocol { implicit val impPerson = jsonFormat1(Person) } ``` and thus serialize it with: ``` import com.example.PersonJsonImplicits._ import spray.json._ new Person("somename").toJson ``` however what If i have ``` trait Animal case class Person(name: String) extends Animal ``` and I have somewhere in my code ``` val animal = ??? ``` and I need to serialize it and I want to use json spray which serializer should I add I was hoping to have something like: ``` object AnimalJsonImplicits extends DefaultJsonProtocol { implicit val impAnimal = jsonFormat???(Animal) } ``` where maybe I needed to add some matcher in order to check of what type is Animal so that if its a person I would direct it to person but found nothing... was reading https://github.com/spray/spray-json and don't understand how to do that.. so how can I serialize the set of ``` trait Animal case class Person(name: String) extends Animal ``` with json spray?