【问题标题】:Scala: How to create a simple nested JSON objectScala:如何创建一个简单的嵌套 JSON 对象
【发布时间】:2021-01-01 09:17:06
【问题描述】:

在 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 对象中创建了我想要的信息的 Map,然后尝试使用 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 对象?

【问题讨论】:

    标签: json scala gson


    【解决方案1】:

    一般来说,没有充分的理由将 GSON 与 Scala 结合使用,因为 GSON 是基于 Java 的,并且并不真正知道如何处理 Scala 集合。在这种情况下,它不知道如何处理 Scala Map 的键值对,而是(很可能是由于反射)只是泄漏了为大小小于 4 的情况。

    Scala 原生的 JSON 库(例如 circe、play-json、spray-json 等)可以满足您对 String-keyed Maps 的期望。他们还内置了对在 Scala 中直接处理 case classes 的支持,例如对于

    case class Foo(id: String, code: Int, notes: String)
    
    val foo = Foo("fooId", 42, "this is a very important foo!")
    

    将序列化为(忽略漂亮打印和字段排序方面可能存在的差异)

    { "id": "fooId", "code": 42, "notes": "this is a very important foo!" }
    

    如果有一个硬项目要求您必须使用 GSON,我相信它确实理解 Java 的集合,因此您可以使用 CollectionConverters 中的转换将 Scala Map 转换为 java.util.Map(在 2.13 中,它是在scala.jdk 包中;在早期版本中,它应该在scala.collection 中)。我不会详细说明这一点,因为我非常强烈的意见是,在 Scala 代码库中,最好使用原生到 Scala JSON 库。

    【讨论】:

      猜你喜欢
      • 2018-12-29
      • 1970-01-01
      • 2020-10-10
      • 2016-10-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-15
      • 1970-01-01
      相关资源
      最近更新 更多