【问题标题】:Non-implicit Writes can't deal with Option (Scala, JSON, Play 2.3.6)非隐式写入无法处理选项(Scala、JSON、Play 2.3.6)
【发布时间】:2014-10-28 04:27:09
【问题描述】:

我有一个这样的案例类:

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

(使用隐式写入,此行有效):

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 和 sellPrice)。原因:这段代码无法编译:

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)),

提前致谢, 拉卡

【问题讨论】:

  • 我发现了类似/相关的问题,还没有确定的答案:stackoverflow.com/questions/25867579/…
  • 我用谷歌搜索了很多东西,并尝试了一些东西,看起来......这是 Play 2.3.6 (?) 中的一个错误。所以在此期间——直到它被修复——我们将不得不使用隐式写入器(?)。
  • 另一个网站上的完全相同的问题,也没有答案(还):grokbase.com/t/gg/play-framework/149g6gt03j/…

标签: json scala playframework-2.0 playframework-json


【解决方案1】:

你的代码有两个问题:

  1. prod 的类型为 Some[Product]。使用val prod: Option[Product] = ...

  2. 您必须使用 Option-Writes:Json.toJson(prod)(Writes.OptionWrites(adminProductWrites))。如果使用隐式写入,则编译器的代码产品完全相同(也使用 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:选项[产品] = 无 产品:选项 [产品] = 无 scala> Json.toJson(prod)(Writes.OptionWrites(adminProductWrites)) res3: play.api.libs.json.JsValue = null

【讨论】:

    猜你喜欢
    • 2017-04-11
    • 1970-01-01
    • 2013-12-31
    • 2020-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-11
    • 2023-03-19
    相关资源
    最近更新 更多