Scala:如何创建一个简单的嵌套 JSON 对象
Scala: How to create a simple nested JSON object
在 Scala 中,我想创建一个 JSON 对象或 JSON 字符串,其结果与此类似(即相对基本的嵌套 JSON):
{
"info":{
"info1":"1234",
"info2":"123456",
"info3":false
},
"x":[
{
"x1_info":10,
"x2_info":"abcde"
}
],
"y":[
{
"y1_info":"28732",
"y2_info":"defghi",
"y3_info":"1261",
"y_extra_info":[
{
"Id":"543890",
"ye1":"asdfg",
"ye2":"BOOLEAN",
"ye3":false,
"ye4":true,
"ye5":true,
"ye6":0,
"ye7":396387
}
]
}
]
}
我计划在测试中使用这个对象,所以理想情况下我可以将 JSON 对象中的信息设置为我想要的任何内容(我不打算为 JSON 对象获取信息来自单独的文件)。我尝试了以下方法,在 JSON 对象中创建了我想要的信息的地图,然后尝试使用 gson 将其转换为 json:
val myInfo = Map(
"info" -> Map("info1" -> "1234",
"info2" -> "123456",
"info3" -> "false"),
"x" -> Map("x1_info" -> 10,
"x2_info" -> "abcde"),
"y" -> Map("y1_info" -> "28732",
"y2_info" -> "defghi",
"y3_info" -> "1261",
"y_extra_info"-> Map("Id" -> "543890",
"ye1" -> "asdfg",
"ye2" -> "BOOLEAN",
"ye3" -> false,
"ye4" -> true,
"ye5" -> true,
"ye6" -> 0,
"ye7" -> 396387
)
)
)
val gson = new GsonBuilder().setPrettyPrinting.create
print(gson.toJson(myInfo))
然而,尽管它正确地生成了 JSON,但并没有在我上面的结构中生成 JSON,而是像这样构造它:
{
"key1": "info",
"value1": {
"key1": "info1",
"value1": "1234",
"key2": "info2",
"value2": "123456",
...(etc)...
我找到了一种不优雅的方法来实现我想要的,方法是创建一个包含我期望的 JSON 的字符串,然后解析为 JSON(但我认为有更好的方法)
val jsonString = "{\"info\":{\"info1\":\"1234\", \"info2\":\"123456\", " +
"\"info3\":false}," +
"\"x\":[{ \"x1_info\":10,\"x2_info\":\"abcde\"}]," +
"\"y\":[{\"y1_info\":\"28732\",\"y2_info\":\"defghi\",\"y3_info\":\"1261\", " +
"\"y_extra_info\":[{" +
"\"Id\":\"543890\",\"ye1\":\"asdfg\"," +
"\"ye2\":\"BOOLEAN\",\"ye3\":false,\"ye4\":true," +
"\"ye5\":true,\"ye6\":0,\"ye7\":396387}]}]}"
我对 Scala 比较陌生,所以也许使用 Map 或将其全部写成字符串并不是最好或最“Scala 方式”?
有没有一种简单的方法可以使用 gson 或 spray 或其他方式创建这样的 JSON 对象?
一般来说,没有充分的理由将 GSON 与 Scala 一起使用,因为 GSON Java-based 并且并不真正知道如何处理 Scala 集合。在这种情况下,它不知道如何处理 Scala Map
的 key-value-ness 而是(很可能是由于反射)只是泄露了默认 Scala Map
的实现细节为小于 4 的情况定制。
JSON Scala 原生的库(例如 circe、play-json、spray-json 等)做你期望的 String
-keyed Map
秒。他们还 built-in 支持在 Scala 中直接处理 case class
es,例如对于
case class Foo(id: String, code: Int, notes: String)
val foo = Foo("fooId", 42, "this is a very important foo!")
将序列化为类似的东西(忽略 pretty-printing 和字段排序可能存在的差异)
{ "id": "fooId", "code": 42, "notes": "this is a very important foo!" }
如果有必须使用 GSON 的硬性项目要求,我相信它确实理解 Java 的集合,因此您可以通过以下方式将 Scala Map
转换为 java.util.Map
使用 CollectionConverters
中的转换(在 2.13 中,它在 scala.jdk
包中;在早期版本中,它应该在 scala.collection
中)。我不打算对此进行详细说明,因为我非常强烈的意见是,在 Scala 代码库中,最好使用 native-to-Scala JSON 库。
在 Scala 中,我想创建一个 JSON 对象或 JSON 字符串,其结果与此类似(即相对基本的嵌套 JSON):
{
"info":{
"info1":"1234",
"info2":"123456",
"info3":false
},
"x":[
{
"x1_info":10,
"x2_info":"abcde"
}
],
"y":[
{
"y1_info":"28732",
"y2_info":"defghi",
"y3_info":"1261",
"y_extra_info":[
{
"Id":"543890",
"ye1":"asdfg",
"ye2":"BOOLEAN",
"ye3":false,
"ye4":true,
"ye5":true,
"ye6":0,
"ye7":396387
}
]
}
]
}
我计划在测试中使用这个对象,所以理想情况下我可以将 JSON 对象中的信息设置为我想要的任何内容(我不打算为 JSON 对象获取信息来自单独的文件)。我尝试了以下方法,在 JSON 对象中创建了我想要的信息的地图,然后尝试使用 gson 将其转换为 json:
val myInfo = Map(
"info" -> Map("info1" -> "1234",
"info2" -> "123456",
"info3" -> "false"),
"x" -> Map("x1_info" -> 10,
"x2_info" -> "abcde"),
"y" -> Map("y1_info" -> "28732",
"y2_info" -> "defghi",
"y3_info" -> "1261",
"y_extra_info"-> Map("Id" -> "543890",
"ye1" -> "asdfg",
"ye2" -> "BOOLEAN",
"ye3" -> false,
"ye4" -> true,
"ye5" -> true,
"ye6" -> 0,
"ye7" -> 396387
)
)
)
val gson = new GsonBuilder().setPrettyPrinting.create
print(gson.toJson(myInfo))
然而,尽管它正确地生成了 JSON,但并没有在我上面的结构中生成 JSON,而是像这样构造它:
{
"key1": "info",
"value1": {
"key1": "info1",
"value1": "1234",
"key2": "info2",
"value2": "123456",
...(etc)...
我找到了一种不优雅的方法来实现我想要的,方法是创建一个包含我期望的 JSON 的字符串,然后解析为 JSON(但我认为有更好的方法)
val jsonString = "{\"info\":{\"info1\":\"1234\", \"info2\":\"123456\", " +
"\"info3\":false}," +
"\"x\":[{ \"x1_info\":10,\"x2_info\":\"abcde\"}]," +
"\"y\":[{\"y1_info\":\"28732\",\"y2_info\":\"defghi\",\"y3_info\":\"1261\", " +
"\"y_extra_info\":[{" +
"\"Id\":\"543890\",\"ye1\":\"asdfg\"," +
"\"ye2\":\"BOOLEAN\",\"ye3\":false,\"ye4\":true," +
"\"ye5\":true,\"ye6\":0,\"ye7\":396387}]}]}"
我对 Scala 比较陌生,所以也许使用 Map 或将其全部写成字符串并不是最好或最“Scala 方式”?
有没有一种简单的方法可以使用 gson 或 spray 或其他方式创建这样的 JSON 对象?
一般来说,没有充分的理由将 GSON 与 Scala 一起使用,因为 GSON Java-based 并且并不真正知道如何处理 Scala 集合。在这种情况下,它不知道如何处理 Scala Map
的 key-value-ness 而是(很可能是由于反射)只是泄露了默认 Scala Map
的实现细节为小于 4 的情况定制。
JSON Scala 原生的库(例如 circe、play-json、spray-json 等)做你期望的 String
-keyed Map
秒。他们还 built-in 支持在 Scala 中直接处理 case class
es,例如对于
case class Foo(id: String, code: Int, notes: String)
val foo = Foo("fooId", 42, "this is a very important foo!")
将序列化为类似的东西(忽略 pretty-printing 和字段排序可能存在的差异)
{ "id": "fooId", "code": 42, "notes": "this is a very important foo!" }
如果有必须使用 GSON 的硬性项目要求,我相信它确实理解 Java 的集合,因此您可以通过以下方式将 Scala Map
转换为 java.util.Map
使用 CollectionConverters
中的转换(在 2.13 中,它在 scala.jdk
包中;在早期版本中,它应该在 scala.collection
中)。我不打算对此进行详细说明,因为我非常强烈的意见是,在 Scala 代码库中,最好使用 native-to-Scala JSON 库。