我有一个这样的案例类:
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))
然后我有一个Option [Product]实例:
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)。当Writes声明为隐式时,我需要按照它的方式工作:
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)
)
}
(使用隐式Writes,此行有效):
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个字段(purchasePrice和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 :(得分:4)
您的代码有两个问题:
prod
的类型为Some[Product]
。使用val prod: Option[Product] = ...
您必须使用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