创建没有组合模式的递归JSON写入

时间:2015-03-12 12:36:12

标签: json scala recursion playframework playframework-json

使用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" -> ??????
    )
}

1 个答案:

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