简体   繁体   English

播放框架-写入部分对象

[英]Play framework - Writes partial object

I have the following object: 我有以下对象:

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

I want to use Writes convertor to write only part of this object. 我想使用Writes转换器仅写入此对象的一部分。 So I tried this code (trying to write the object without the age): 因此,我尝试了以下代码(尝试编写没有年龄限制的对象):

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

But this obviously doesn't compile. 但这显然无法编译。 Is there a way to make this work? 有没有办法使这项工作?

You can do this, but you can't reference A.unapply . 您可以执行此操作,但不能引用A.unapply Part of the conciseness of JSON combinators comes from the apply and unapply methods that are automatically generated by the compiler for case classes. JSON组合器的部分简洁性来自于编译器针对案例类自动生成的applyunapply方法。 But these methods use all of the parameters in the class. 但是这些方法使用了类中的所有参数。

A.unapply has the signature A => Option[(Long, String, Option[String], Int)] . A.unapply具有签名A => Option[(Long, String, Option[String], Int)] This is incompatible with combinators that only cover three fields (instead of all four). 这与仅覆盖三个字段(而不是全部四个)的组合器不兼容。 You have two options. 您有两个选择。

1) Write another unapply -like method that has the correct signature: 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) Manually create the Writes as an anonymous class: 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
  )
}

Option 1) from @mz can be put more succinctly as: @mz中的选项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))

FYI, you can achieve that like the following. 仅供参考,您可以实现以下目标。 (This is just a suggestion.) (这只是一个建议。)

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM