在Scala中使用Play Framework 2:解析可变参数JSON格式?

时间:2015-09-24 12:50:21

标签: json scala playframework playframework-2.0

考虑以下示例JSON:

properties: {
    "key1": "a",
    "key2": 1,
    "key3": null,
    "key4": 0.56
    ....
    "key99": "zzzzz"
}

我的代码需要能够将其解析为某种Scala结构(case类?)并返回JSON。

对我而言,由于properties内部的元素数量不多,因此看起来像Map[String, T]。并且因为每个内部属性的值可以是多种类型,所以我不完全确定如何将其表示为有限的Scala结构。关于隐式ReadsWritesFormats的文档对我有意义,但它们似乎没有处理更复杂的示例,如上所述。

我完全有可能在考虑这个完全错误。

我是框架(以及语言)的新手,我很难理解如何表达这一点 - 任何见解都会受到高度赞赏。

1 个答案:

答案 0 :(得分:1)

正如@Tyth指出的那样,我们可能想重新考虑你的json的结构。也许是这样的:

{ [ { "key" : "key1", "value" : "a" }, { "key" : "key2", "value" : "1" }, .....

会更好......

然而,要回答你的问题,你可以这样做:

import play.api.libs.json._
val a = """{
 |     "key1": "a",
 |     "key2": 1,
 |     "key3": null,
 |     "key4": 0.56 }
 | """
 val b = Json.parse(a)
 val keys = b.as[JsObject].keys

您可以打印钥匙

scala> keys.foreach { k => println( b \ k ) }
"a"
1
null
0.56

然后转入JsValue的地图

scala> keys.map { k => k -> (b \ k) }.toMap
res4: scala.collection.immutable.Map[String,play.api.libs.json.JsValue] = Map(key1 -> "a", key2 -> 1, key3 -> null, key4 -> 0.56)

Or Strings:

scala> keys.map { k => k -> (b \ k).toString }.toMap
res3: scala.collection.immutable.Map[String,String] = Map(key1 -> "a", key2 -> 1, key3 -> null, key4 -> 0.56)

编辑(根据补充评论):

    scala> JsObject(b.as[JsObject].fields :+  ("key99" -> JsString("zzzz")))
res7: play.api.libs.json.JsObject = {"key1":"a","key2":1,"key3":null,"key4":0.56,"key99":"zzzz"}