使用JSON组合器时,可以使用documentation中所述的lazyWrite
创建递归结构:
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" -> ??????
)
}
答案 0 :(得分:2)
是。事实上,很容易。
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))