我有以下对象:
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))
但这显然不能编译。 有没有办法使这项工作?
答案 0 :(得分:3)
您可以执行此操作,但无法引用A.unapply
。 JSON组合器的部分简洁性来自编译器为案例类自动生成的apply
和unapply
方法。但是这些方法使用了类中所有的参数。
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)
选项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))