[英]Converting “recursive” object to JSON (Play Framework 2.4 with Scala)
我已经达到了我的代码可以成功编译的地步,但是我对我的解决方案有疑问,并出于这个原因发布了这个问题。
我有一个Node类定义为:
case class Node(id: Long, label: String, parent_id: Option[Long])
我引用/取消引用递归的原因是因为从技术上讲,我不在节点内存储节点。 相反,每个节点都有一个指向其父节点的指针,我可以说:给我所有Node id = X的子节点。
为了可视化,这是一个示例树。 我想提供root_node的ID,并获取树到Json字符串的转换:
root_node
|_ node_1
| |_ node_11
| |_ node_111
|_ node_2
|_ node_3
Json看起来像:
{"title": "root_node", "children": [...]}
子数组包含node_1、2和3等...递归地
这是节点的Writes Converter:
/** json converter of Node to JSON */
implicit val NodeWrites = new Writes[Node] {
def writes(node: Node) = Json.obj(
"title" -> node.label,
"children" -> Node.getChildrenOf(node.id)
)
}
引用播放文档:
Play JSON API为大多数基本类型(例如Int,Double,String和Boolean)提供隐式Writes。 它还支持Writes [T]存在的任何T类型集合的Writes。
我需要指出,Node.getChildrenOf(node.id)从数据库返回一个节点列表。 因此,根据Play的文档,我应该能够将List [Node]转换为Json。 似乎在Writes转换器本身中执行此操作比较麻烦。
这是运行此代码导致的错误:
type mismatch;
found : List[models.Node]
required: play.api.libs.json.Json.JsValueWrapper
Note: implicit value NodeWrites is not applicable here because it comes after the application point and it lacks an explicit result type
我在“写入”转换器中添加了“显式结果类型”,结果如下:
/** json converter of Node to JSON */
implicit val NodeWrites: Writes[Node] = new Writes[Node] {
def writes(node: Node) = Json.obj(
"title" -> node.label,
"children" -> Node.getChildrenOf(node.id)
)
}
现在,代码可以正确执行,我可以在浏览器中可视化该树。
即使在我看来这是最干净的解决方案,但IntelliJ仍然抱怨这条线:
"children" -> Node.getChildrenOf(node.id)
说:
Type mismatch: found(String, List[Node]), required (String, Json.JsValueWrapper)
可能是IntelliJ的错误报告不是基于Scala编译器吗?
最后,JSON转换器的整体方法糟糕吗?
谢谢,对不起,很长的帖子。
问题出在"children" -> Node.getChildrenOf(node.id)
。 Node.getChildrenOf(node.id)
返回一个List[Node]
。 而Json.obj
任何属性Json.obj
需要JsValueWrapper
。 在这种情况下为JsArray
。
这样的事情应该起作用:
implicit val writes = new Writes[Node] {
def writes(node: Node) = Json.obj(
"title" -> node.label,
// Note that we have to pass this since the writes hasn't been defined just yet.
"children" -> JsArray(Node.getChildrenOf(node).map(child => Json.toJson(child)(this)))
)
}
至少可以编译,但是我还没有用任何数据对其进行过测试。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.