spray-jsonでケースクラスをトレイトでシリアライズ・デシリアライズする
spray-jsonでケースクラスをトレイトでシリアライズ・デシリアライズしようと思ったときに悩んだのでメモ。
trait Animal case class Cat(name: String) extends Animal // Animalで変換したい
こんな感じのを変換したい場合
import spray.json._ import DefaultJsonProtocol._ trait Animal case class Cat(name: String, kind: String = "cat") extends Animal implicit val CatFormat = jsonFormat2(Cat) implicit object AnimalFormat extends RootJsonFormat[Animal] { def write(obj: Animal): JsValue = obj match { case cat: Cat => cat.toJson } def read(json: JsValue): Animal = json.asJsObject.fields("kind") match { case JsString("cat") => json.convertTo[Cat] } } val animal: Animal = Cat("tama") val json = animal.toJson val animal2 = json.convertTo[Animal] println(animal) // Cat(tama,cat) println(json) // {"kind":"cat","name":"tama"} println(animal2) // Cat(tama,cat)
こうすればできる
AnimalFormat
オブジェクトのread
メソッドのjson.asJsObject.fields("kind")
の部分は最初に見つけたのを使っているだけなのでもっといいやり方があるかもしれないです。