重头戏2.1特性的Json序列化

重头戏2.1特性的Json序列化,json,scala,playframework-2.0,Json,Scala,Playframework 2.0,Play2.1中实验性的“Inception”特性(Json.format[…])只适用于案例类(请参阅)。如何为一个特性编写自定义隐式格式。我有以下结构: sealed trait Plan { def id: String def name: String def apps: Int def users: Int def testruns: Int def price: Int def prio: Int } 下面是扩展trait计划的case类 case cl

Play2.1中实验性的“Inception”特性(Json.format[…])只适用于案例类(请参阅)。如何为一个特性编写自定义隐式格式。我有以下结构:

sealed trait Plan {
  def id: String
  def name: String
  def apps: Int
  def users: Int
  def testruns: Int
  def price: Int
  def prio: Int
}
下面是扩展trait计划的case类

case class Start(
                  id: String = "start",
                  name: String = "Start",
                  apps: Int = 1,
                  users: Int = 1,
                  testruns: Int = 10,
                  price: Int = 99,
                  prio: Int = 30) extends Plan

case class Pro(
                id: String = "pro",
                name: String = "Pro",
                apps: Int = 2,
                users: Int = 5,
                testruns: Int = 25,
                price: Int = 299,
                prio: Int = 20) extends Plan

case class Premium(
                    id: String = "premium",
                    name: String = "Premium",
                    apps: Int = -1,
                    users: Int = -1,
                    testruns: Int = -1,
                    price: Int = 799,
                    prio: Int = 10) extends Plan
现在我需要在Plan companion对象中编写自定义隐式格式val。我试过:

object Plan {
  implicit val planFormats = (
    (__ \ "id").format[String] and
    (__ \ "name").format[String] and
    (__ \ "apps").format[Int] and
    (__ \ "users").format[Int] and
    (__ \ "testruns").format[Int] and
    (__ \ "price").format[Int] and
    (__ \ "prio").format[Int]
  )(Plan.apply, unlift(Plan.unapply))
}

然而,trait没有应用或不应用的方法。在Play 2.1中,为json序列化提供隐式val的正确方法是什么

您只需提供自己的函数即可根据给定值创建新实例

本质上是作为工厂的特性的伴生对象

object Plan {
  def apply(id: String, name: String, ...) = id match {
    case "pro" => new Pro(id, name, ...)
    ...
  }

  def unapply(p: Person): Option[(String, String, ...)] = ...
}

为什么要使用Traits并实现case类

为什么不使用类的实例,例如:

case class Plan (
  id: String,
  name: String,
  apps: Int,
  users: Int,
  testruns: Int,
  price: Int,
  prio: Int
)

val start = new Plan("start", "Start", 1, 1, 10, 99, 30)
val pro = new Plan("pro", "Pro", 2, 5, 25, 299, 20)
val premium = new Plan("premium", "Premium", -1, -1, -1, 799, 10)
然后,您可以保留Json格式化程序:

object Plan {
  implicit val planFormats = (
    (__ \ "id").format[String] and
    (__ \ "name").format[String] and
    (__ \ "apps").format[Int] and
    (__ \ "users").format[Int] and
    (__ \ "testruns").format[Int] and
    (__ \ "price").format[Int] and
    (__ \ "prio").format[Int]
  )(Plan.apply, unlift(Plan.unapply))
}

在这种情况下,它的工作!您只需要将“case class Plan”上的花括号更改为括号。谢谢你的解决方案。如果Plan是一个case类,我甚至可以再次使用“implicit val planFormats=Json.format[Plan]”,而不是编写自定义格式。然而,我仍然对如何为trait.Thx编写一个隐含的自定义格式感兴趣,这是有意义的。在本例中,unapply方法是什么样子的?抱歉,我对Scala还是新手。unapply的做法正好相反-从case类创建一个元组。只需在REPL中尝试,例如,
Start.unapply
创建一个从Start到n元组参数选项的函数。