Play框架 - 写入部分对象

时间:2015-11-16 22:00:28

标签: json scala playframework-2.0

我有以下对象:

case class A(id: Long, name:String, lastName:Option[String], age:Int)

我想使用Writes convertor只写入此对象的一部分。 所以我尝试了这段代码(尝试编写没有年龄的对象):

implicit val aWrites: Writes[A] = (
  (JsPath \ "it").write[Long] and
  (JsPath \ "name").write[String] and 
  (JsPath \ "lastName"). writeNullable[String]
)(unlift(A.unapply))

但这显然不能编译。 有没有办法使这项工作?

3 个答案:

答案 0 :(得分:3)

您可以执行此操作,但无法引用A.unapply。 JSON组合器的部分简洁性来自编译器为案例类自动生成的applyunapply方法。但是这些方法使用了类中所有的参数。

A.unapply具有签名A => Option[(Long, String, Option[String], Int)]。这与仅覆盖三个字段(而不是全部四个字段)的组合器不兼容。你有两个选择。

1)编写另一个具有正确签名的unapply方法:

def unapplyShort(a: A): Option[(Long, String, Option[String], Int)] =
    Some((a.id, a.name, a.lastName))

implicit val aWrites: Writes[A] = (
  (JsPath \ "id").write[Long] and
  (JsPath \ "name").write[String] and 
  (JsPath \ "lastName").writeNullable[String]
)(unlift(unapplyShort))

2)手动创建Writes作为匿名类:

implicit val aWrites: Writes[A] = new Writes[A] {
  def writes(a: A): JsValue = Json.obj(
    "id" -> a.id,
    "name" -> a.name,
    "lastName" -> a.lastName
  )
}

答案 1 :(得分:1)

来自@ m-z的

选项1)可以更简洁地表达为:

implicit val aWrites: Writes[A] = (
  (JsPath \ "id").write[Long] and
  (JsPath \ "name").write[String] and
  (JsPath \ "lastName").writeNullable[String]
)((a) => (a.id, a.name, a.lastName))

答案 2 :(得分:0)

仅供参考,你可以像下面这样实现。 (这只是一个建议。)

object noWrites extends OWrites[Any] {
  override def writes(o: Any): JsObject = JsObject(Seq())
}

implicit val aWrites: Writes[A] = (
  (JsPath \ "id").write[Long] and
  (JsPath \ "name").write[String] and
  (JsPath \ "lastName").writeNullable[String] and noWrites // <---
)(unlift(A.unapply))