[英]Implicit serializing case class to Json with play.api.libs.json
[英]Is it possible to override the way play.api.libs.json write options?
我與Play合作! Scala 2.4,我有幾個簡單的案例類,例如:
case class A(a: Option[String])
當該選項為空時,我想重寫Json.toJson(A)的工作方式。
這是我所做的:
implicit val aWrites: Writes[A] = Json.writes[A]
implicit def ow[T](implicit w: Writes[T]): Writes[Option[T]] = Writes {
case None => JsString("[]")
case Some(t) => Json.toJson(t)
}
Json.toJson(A(a = None)) mustBe Json.parse("""{"a":"[]"}""")
但是它仍然像往常一樣解析類(例如,用{}
代替{"a":"[]"}
)。
我要怎么做才能通過測試?
使用Json.writes
宏是不可能的,因為它是專門為處理Option
而使用readNullable[B]
編寫的。 這意味着您將需要使用組合器來定義Writes[A]
。 不幸的是,為僅具有一個字段的對象定義Writes
比具有更多字段的對象麻煩一些。
implicit val aWrites: Writes[A] = Writes(a => Json.obj("a" -> a.a))
scala> Json.toJson(A(None))
res8: play.api.libs.json.JsValue = {"a":"[]"}
具有多個字段的示例:
import play.api.libs.functional.syntax._
import play.api.libs.json._
case class A(a: Option[String], b: Int)
implicit val aWrites: Writes[A] = (
(__ \ "a").write[Option[String]] and
(__ \ "b").write[Int]
)(unlift(A.unapply))
scala> Json.toJson(A(None, 10))
res0: play.api.libs.json.JsValue = {"a":"[]","b":10}
您需要使用以下內容更改aWrites
,以添加"a":
部分:
implicit val aWrites: Writes[A] = new Writes[A] {
override def writes(o: A): JsValue =
Json.obj("a" -> Json.toJson(o.a))
}
編輯:使用Writes
對象的apply
方法對於Scala來說更清楚和更好,因此我建議您使用@mz的答案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.