2014-10-28 51 views
1

我有一類情況是這樣的:非隱含寫入不能與期權交易(斯卡拉,JSON,播放2.3.6)

case class Product(ean: Long, name: String, description: String, purchasePrice: Option[BigDecimal] = None, sellingPrice: Option[BigDecimal] = None) 

而且我有一個這樣的非隱寫道:

val adminProductWrites = (
    (JsPath \ "ean").write[Long] and 
    (JsPath \ "name").write[String] and 
    (JsPath \ "description").write[String] and 
    (JsPath \ "purchase_price").writeNullable[BigDecimal] and 
    (JsPath \ "selling_price").writeNullable[BigDecimal] 
)(unlift(Product.unapply)) 

然後,我有選擇的實例[產品]:

val prod = Some(Product(5018206244611L, "Zebra Paperclips", "Zebra Length 28mm Assorted 150 Pack")) 

當我試圖連載吧...:

val jsonStr = Json.toJson(prod) (adminProductWrites) 

我得到了這樣的錯誤:

<console>:21: error: type mismatch; 
found : play.api.libs.json.OWrites[Product] 
required: play.api.libs.json.Writes[Some[Product]] 
     val jsonStr = Json.toJson(prod) (adminProductWrites) 

所以,第一個(只作比較)我嘗試這樣做:

val jsonStr = Json.toJson(prod.get) (adminProductWrites) 

它的工作原理:

jsonStr: play.api.libs.json.JsValue = {"ean":5018206244611,"name":"Zebra Paperclips","description":"Zebra Length 28mm Assorted 150 Pack"} 

但我不想那樣做(調用.get)。我需要工作時寫操作被聲明爲隱它的方式:

implicit object ProductWrites extends Writes[Product] { 
    def writes(p: Product) = Json.obj(
    "ean" -> Json.toJson(p.ean), 
    "name" -> Json.toJson(p.name), 
    "description" -> Json.toJson(p.description) 
) 
} 

(有內隱寫道,該行工作):

scala> val jsonStr = Json.toJson(prod) 
jsonStr: play.api.libs.json.JsValue = {"ean":5018206244611,"name":"Zebra Paperclips","description":"Zebra Length 28mm Assorted 150 Pack"} 

我缺少什麼?


附加說明:

我的隱寫操作是不完整的,我特意去掉最後2場(進價和sellingPrice)。原因:此代碼不能編譯:

implicit object ProductWrites extends Writes[Product] { 
    def writes(p: Product) = Json.obj(
    "ean" -> Json.toJson(p.ean), 
    "name" -> Json.toJson(p.name), 
    "description" -> Json.toJson(p.description), 
    "purchase_price" -> p.purchasePrice.getOrElse(None), 
    "selling_price" -> p.sellingPrice.getOrElse(None) 
) 

}

我給出了這樣的錯誤:

<console>:24: error: No Json serializer found for type Serializable. Try to implement an implicit Writes or Format for this type. 
     "purchase_price" -> Json.toJson(p.purchasePrice.getOrElse(None)), 

由於提前, 拉嘎

+0

我發現了類似/相關問題,沒有蓋棺定論的答案: HTTP://計算器。com/questions/25867579/play-2-3-scala-explicit-passing-writer-needs-to-match-optiont-vs-t-impli – 2014-10-28 04:49:42

+0

我已經搜遍了所有東西,並嘗試了幾件事情,看起來像。 ..這是Play 2.3.6(?)中的一個錯誤。因此,在此期間 - 直到它被修復 - 我們必須與隱式作家(?)合作。 – 2014-10-28 05:23:27

+0

在另一個網站上完全相同的問題,也沒有答案(尚未):http://grokbase.com/t/gg/play-framework/149g6gt03j/2-3-scala-explicitly-passing-writer-needs-to- match-option-t-vs-t-implicit-writer-can-handle-both – 2014-10-28 05:33:04

回答

4

你的代碼有兩個問題:

  1. prod類型爲Some[Product]。使用val prod: Option[Product] = ...

  2. 您必須使用Option-Writes:Json.toJson(prod)(Writes.OptionWrites(adminProductWrites))。如果使用隱式Writes,則編譯器的代碼產品完全相同(也使用OptionWrites)。

 

    scala> val prod: Option[Product] = Some(Product(5018206244611L, "Zebra Paperclips", "Zebra Length 28mm Assorted 150 Pack")) 
     prod: Option[Product] = Some(Product(5018206244611,Zebra Paperclips,Zebra Length 28mm Assorted 150 Pack,None,None)) 

    scala> Json.toJson(prod)(Writes.OptionWrites(adminProductWrites)) 
     res2: play.api.libs.json.JsValue = {"ean":5018206244611,"name":"Zebra Paperclips","description":"Zebra Length 28mm Assorted 150 Pack"} 

    scala> val prod: Option[Product] = None 
     prod: Option[Product] = None 

    scala> Json.toJson(prod)(Writes.OptionWrites(adminProductWrites)) 
     res3: play.api.libs.json.JsValue = null 

+0

謝謝!有用。 – 2014-10-28 17:36:16