6

我正在尝试在 Play Framework 2.1.3 中处理 Ajax POST 请求。发布数据是一个 JSON 对象,具有如下树结构:

{ id: "a", name: "myname", kids : [{ id: "a1", name : "kid1", kids: []}, {id: "a2", name: "kid2", kids: [{id: "aa1", name :"grandkid", kids: []}]}]

我想把'孩子'嵌套得任意深。我想到的课程是这样的(我意识到递归可能有问题):

case class Person {
  id: String,
  name: String,
  kids: Array[Person]
}

我会想到的格式:

implicit val personFormat:Format[Person] = Json.format[Person]

Play 在我写的格式上抛出错误:

类型不匹配; 找到:controllers.Resources.Person 需要:Array[controllers.Resources.Person]

我知道 Play 有一个树结构。我找不到有关如何将其与 JSON 读取联系起来的示例/文档。

非常感谢任何帮助,谢谢

4

2 回答 2

10

您将需要一个递归 val,例如:

implicit val jsonReads: Reads[Person] = ((__ \ "id").read[String] and (__ \ "name").read[String] and (__ \ "kids").read[Seq[Person]])(apply _)

(我已将集合类型从 Array 更改为 Seq,因为它更通用,并且允许您在不影响下线代码的情况下更改实现。)

这是使用此处记录的语法。

于 2013-10-26T19:08:21.160 回答
2

我看到这项工作的唯一方法是在您的 Person 案例类中使用 JsArray 或 Array[String] 而不是 Array[Person] 。JSON 宏 Inception 只能为已经存在隐式 JSON 读 + 写代码的对象生成基元和列表、映射和数组的读 + 写代码。本质上,您不能拥有引用自身的案例类。

package models

import play.api.libs.json._

case class Person(
  id   : String,
  name : String,
  kids : JsArray
)

object Person extends ((String,String,JsArray) => Person) {

  implicit val jsonFormat = Json.format[Person]

}
于 2013-10-26T19:01:33.990 回答