2013-05-06 32 views
2

Play 2.1(Json.format [...])中的实验性“初始”特征仅适用于案例分类(请参阅here)。我如何编写隐含于特质的自定义格式。我有以下结构:Play 2.1 Json序列化特征

sealed trait Plan { 
    def id: String 
    def name: String 
    def apps: Int 
    def users: Int 
    def testruns: Int 
    def price: Int 
    def prio: Int 
} 

以下是扩展特质计划的案例类。

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伴侣对象中编写自定义隐式格式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)) 
} 

但是,特质没有适用或不适用的方法。在Play 2.1中为json序列化提供隐式val的正确方法是什么?

回答

5

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

基本上是充当工厂的特性的伴侣对象。

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

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

THX,有意义。在这个例子中,应用程序的方法如何?对不起,我还是斯卡拉新手。 – 2013-05-06 15:51:37

+0

unapply完全相反 - 从案例类创建一个元组。只需在REPL中尝试一下,例如'Start.unapply _'创建一个从开始到参数n元组选项的函数。 – 2013-05-06 17:21:19

+0

谢谢,它的作品。 – 2013-05-06 19:08:41

1

为什么你使用Traits和实现案例类?

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

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)) 
} 
+1

在这种情况下,它的工作原理!您只需将“case class plan”上的大括号更改为括号。感谢您的解决方案。如果Plan是一个案例类,我甚至可以再次使用“隐式val planFormats = Json.format [Plan]”,而不是编写自定义格式。 但是,我仍然有兴趣如何编写一个隐含的性格自定义格式。 – 2013-05-06 15:42:51

+0

谢谢,我更新了答案。 – 2013-05-07 07:55:47