使用带有unapply的Writes trait仅序列化特定属性

时间:2015-05-25 18:27:44

标签: json scala serialization playframework

让我想象我有一个这样的案例类:

case class Product(ean: Long, name: String, description: String)

我希望将此类的对象序列化为Json,我可以像这样实现Writes特性:

implicit val productWrites: Writes[Product] = (
  (JsPath \ "ean").write[Long] and
  (JsPath \ "name").write[String] and
  (JsPath \ "description").write[String]
)(unlift(Product.unapply))

如果我想序列化对象的所有属性,这可以正常工作。现在我们可以说我不想序列化ean。我试过这样的事情:

implicit val productWrites: Writes[Product] = (
  (JsPath \ "name").write[String] and
  (JsPath \ "description").write[String]
)(unlift(Product.unapply))

这似乎不起作用,因为需要使用unapply方法返回的所有字段/属性。

有没有办法让第二个序列化方法只使用我想要序列化的属性,或者我必须使用这样的东西:

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

这是唯一的方法吗?

2 个答案:

答案 0 :(得分:3)

unlift(Product.unapply)的类型为Product => (Long, String, String)

在这种情况下,参数的类型应为Product => (String, String)。您可以编写如下的函数文字。

implicit val productWrites: Writes[Product] = (
  (JsPath \ "name").write[String] and
  (JsPath \ "description").write[String]
)(p => (p.name, p.description))

答案 1 :(得分:1)

我认为你的最后一个例子是要走的路。这是使用隐式val而不是隐式对象执行相同操作的另一种方法:

implicit val productWrites: Writes[Product] = Writes { p =>
  Json.obj(
    "name" -> Json.toJson(p.name),
    "description" -> Json.toJson(p.description)
  )
}