创建递归 JSON 没有组合器模式的写入
Create recursive JSON Writes without combinator pattern
使用 JSON 组合器时,可以使用 lazyWrite
创建递归结构,如 documentation:
中所述
implicit lazy val userWrites: Writes[User] = (
(__ \ "name").write[String] and
(__ \ "friends").lazyWrite(Writes.seq[User](userWrites))
)(unlift(User.unapply))
是否可以在实现写入的同时做到这一点,即:
implicit lazy val userWrites: Writes[User] = new Writes[User]{
def writes(user: User) = Json.obj(
"name" -> user.name,
"friends" -> ??????
)
}
是的。其实很简单。
implicit lazy val userWrites: Writes[User] = new Writes[User] {
def writes(user: User) = Json.obj(
"name" -> user.name,
"friends" -> user.friends
)
}
val joe = User("Joe", Nil)
val bob = User("Bob", Nil)
val jane = User("Jane", Seq(bob, joe))
val james = User("James", Seq(bob, jane))
scala> Json.toJson(james)
res0: play.api.libs.json.JsValue = {"name":"James","friends":[{"name":"Bob","friends":[]},{"name":"Jane","friends":[{"name":"Bob","friends":[]},{"name":"Joe","friends":[]}]}]}
userWrites
其实也不需要偷懒。它像这样工作得很好,因为组合器试图通过隐式解析子写入并在树下工作来生成写入,这就是为什么它需要 lazyWrite
来阻止它在递归结构中无限下降。当写入 def writes
时,我们明确说明了写入的内容。
但是,这两种方法都不能使您免于这种情况:
def jim: User = User("Joe", Seq(dwight))
def dwight: User = User("Bob", Seq(jim))
使用 JSON 组合器时,可以使用 lazyWrite
创建递归结构,如 documentation:
implicit lazy val userWrites: Writes[User] = (
(__ \ "name").write[String] and
(__ \ "friends").lazyWrite(Writes.seq[User](userWrites))
)(unlift(User.unapply))
是否可以在实现写入的同时做到这一点,即:
implicit lazy val userWrites: Writes[User] = new Writes[User]{
def writes(user: User) = Json.obj(
"name" -> user.name,
"friends" -> ??????
)
}
是的。其实很简单。
implicit lazy val userWrites: Writes[User] = new Writes[User] {
def writes(user: User) = Json.obj(
"name" -> user.name,
"friends" -> user.friends
)
}
val joe = User("Joe", Nil)
val bob = User("Bob", Nil)
val jane = User("Jane", Seq(bob, joe))
val james = User("James", Seq(bob, jane))
scala> Json.toJson(james)
res0: play.api.libs.json.JsValue = {"name":"James","friends":[{"name":"Bob","friends":[]},{"name":"Jane","friends":[{"name":"Bob","friends":[]},{"name":"Joe","friends":[]}]}]}
userWrites
其实也不需要偷懒。它像这样工作得很好,因为组合器试图通过隐式解析子写入并在树下工作来生成写入,这就是为什么它需要 lazyWrite
来阻止它在递归结构中无限下降。当写入 def writes
时,我们明确说明了写入的内容。
但是,这两种方法都不能使您免于这种情况:
def jim: User = User("Joe", Seq(dwight))
def dwight: User = User("Bob", Seq(jim))