簡體   English   中英

播放框架-寫入部分對象

[英]Play framework - Writes partial object

我有以下對象:

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

我想使用Writes轉換器僅寫入此對象的一部分。 因此,我嘗試了以下代碼(嘗試編寫沒有年齡限制的對象):

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

但這顯然無法編譯。 有沒有辦法使這項工作?

您可以執行此操作,但不能引用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
  )
}

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

僅供參考,您可以實現以下目標。 (這只是一個建議。)

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