Scala/Play:将 JSON 解析为 Map 而不是 JsObject
在Play Framework的主页上,他们声称“JSON是一等公民”。我还没有看到这方面的证据。
在我的项目中,我正在处理一些非常复杂的JSON结构。这只是一个非常简单的例子:
{
"key1": {
"subkey1": {
"k1": "value1"
"k2": [
"val1",
"val2"
"val3"
]
}
}
"key2": [
{
"j1": "v1",
"j2": "v2"
},
{
"j1": "x1",
"j2": "x2"
}
]
}
现在我明白了Play正在使用Jackson来解析JSON。我在我的Java项目中使用Jackson,我会做一些简单的事情,比如这样:
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> obj = mapper.readValue(jsonString, Map.class);
这将很好地将我的JSON解析为Map对象,这就是我想要的 - 字符串和对象对的Map,并允许我轻松地将数组转换为。ArrayList
Scala/Play 中的相同示例如下所示:
val obj: JsValue = Json.parse(jsonString)
相反,这给了我一个专有类型,这并不是我所追求的。JsObject
我的问题是:我能否在Scala/Play中解析JSON字符串,而不是像在Java中那样容易地进行解析?Map
JsObject
题外话:在Scala/Play中使用而不是使用的原因是什么?JsObject
Map
我的堆栈: Play Framework 2.2.1 / Scala 2.10.3 / Java 8 64bit / Ubuntu 13.10 64bit
更新:我可以看到特拉维斯的答案是赞成的,所以我想这对每个人都有意义,但我仍然没有看到如何应用它来解决我的问题。假设我们有这个例子(jsonString):
[
{
"key1": "v1",
"key2": "v2"
},
{
"key1": "x1",
"key2": "x2"
}
]
好吧,根据所有方向,我现在应该放入所有我不理解其目的的样板:
case class MyJson(key1: String, key2: String)
implicit val MyJsonReads = Json.reads[MyJson]
val result = Json.parse(jsonString).as[List[MyJson]]
看起来不错,对吧?但是等一下,数组中还有另一个元素,这完全破坏了这种方法:
[
{
"key1": "v1",
"key2": "v2"
},
{
"key1": "x1",
"key2": "x2"
},
{
"key1": "y1",
"key2": {
"subkey1": "subval1",
"subkey2": "subval2"
}
}
]
第三个元素不再匹配我定义的 case 类 - 我又回到了原点。我每天都可以在Java中使用如此复杂的JSON结构,Scala是否建议我应该简化我的JSON以适应它的“类型安全”策略?如果我错了,请纠正我,但是我通过这种语言应该提供数据,而不是相反?
更新2:解决方案是将Jackson模块用于scala(我的答案中的示例)。