2013-11-22 10 views
5

この質問は、JSONからケースクラスNode [Bird]を逆シリアル化しようとする次の例に基づいています。前述の例でPlay2.2 ScalaのJSONへの/からの汎用ケースクラスの自動直列化/逆シリアル化

import play.api.libs.json._ 
import play.api.libs.functional.syntax._ 

object ValidationTest { 

    case class Node[T](_id: Int, thing: T) 

    case class Bird(name: String, color: String) 

    // ERROR -- No apply function found matching unapply parameters 
    implicit val birdNodeFormat = Json.format[Node[Bird]] 

    val birdNodesJson: JsValue = Json.arr(
    Json.obj(
     "_id" -> 0, 
     "thing" -> Json.obj(
      "name" -> "Cardinal", 
      "color" -> "Red" 
    ) 
    ), 
    Json.obj(
     "_id" -> 1, 
     "thing" -> Json.obj(
     "name" -> "Bluejay", 
     "color" -> "Blue" 
    ) 
    ) 
) 

    val birdNodesResult = birdNodesJson.validate[Seq[Node[Bird]]] 

} 

、Scalaは形式マクロのノードのための適切な適用/適用を解除機能[鳥]を解決することができません。

// ERROR -- No apply function found matching unapply parameters 
    implicit val birdNodeFormat = Json.format[Node[Bird]] 

ただし、BirdNodeなどの非汎用ケースクラスの使用には問題ありません。

case class BirdNode(_id: Int, thing: Bird) 

    // WORKS 
    implicit val birdNodeFormat = Json.format[BirdNode] 

    ... 

    // WORKS 
    val birdNodesResult = birdNodesJson.validate[Seq[BirdNode]] 

/シリアライズプレイ2.2にJSONから/へのノード[鳥]のようなものをデシリアライズするための最良の方法は何ですか?

答えて

1

マクロを使用せずにNode[T]のためのフォーマットを定義する必要があるかもしれませんが、これは動作します:

implicit val birdFormat: Format[Bird] = Json.format[Bird] 

implicit def nodeFormat[T : Format]: Format[Node[T]] = 
    ((__ \ "_id").format[Int] ~ 
    (__ \ "thing").format[T] 
)(Node.apply, unlift(Node.unapply)) 
+0

すごいです!私はアンリフト機能を使わずにこれを試していたことが分かります。注釈として、unapply関数はOption [(arg1、arg2、...)]を返し、それが書き込みに必要な(arg1、arg2、...)を提供しないようにします。 [ScalaJsonCombinators](http://www.playframework.com/documentation/2.2.x/ScalaJsonCombinators)を参照してください。 – johnh

関連する問題