2013-05-06 52 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