在Play2.2 Scala中将通用案例类自动序列化/反序列化为JSON

时间:2013-11-22 00:17:20

标签: json scala generics playframework-2.2

此问题基于以下示例,该示例尝试从JSON反序列化案例类Node [Bird]。

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无法为格式宏解析Node [Bird]的正确apply / unapply函数。

  // 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]]

在Play 2.2中将节点[Bird]序列化/反序列化为JSON的最佳方法是什么?

1 个答案:

答案 0 :(得分: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))
相关问题