【问题标题】:Gson write to nested objectsGson 写入嵌套对象
【发布时间】:2020-08-14 23:05:18
【问题描述】:

在 Gson 中,我如何写入子字段/嵌套对象。这是我当前的代码:

    Path usersPath = Paths.get("src/users.json");
    Gson usersGson = new GsonBuilder().setPrettyPrinting().create();


    try (BufferedReader usersReader = Files.newBufferedReader(usersPath);
        BufferedWriter usersWriter = Files.newBufferedWriter(usersPath, StandardOpenOption.WRITE)) {
        JsonObject usersObject = usersGson.fromJson(usersReader, JsonObject.class);
        
        usersObject.addProperty("example", 123);
        usersGson.toJson(usersObject, usersWriter);

    } catch (IOException e) {
        e.printStackTrace();
    }

如何让 users.json 看起来像这样:

{
  "example1": {
    "example2": {
      "example3": 4
    }
  }
}

【问题讨论】:

    标签: java json gson


    【解决方案1】:

    将JSON作为字符串处理(因此跳过文件读写,仅用于此演示),我将展示两种基本方法:

    1) 使用 Java 地图

    import java.util.Map;
    import java.util.HashMap;
    
    ...
    
    Map<String, Integer> ex3 = new HashMap();
    ex3.put("example3", 4);
    Map<String, Map<String, Integer>> ex2 = new HashMap();
    ex2.put("example2", ex3);
    Map<String, Map<String, Map<String, Integer>>> ex1 = new HashMap();
    ex1.put("example1", ex2);
            
    String json = new Gson().toJson(ex1);
    System.out.println(json);
    

    在这种情况下,我们手动构建嵌套地图。输出是:

    {"example1":{"example2":{"example3":4}}}
    

    2) 使用 POJO(或多个 POJO)

    在这种情况下,我将使用一个包含 2 个嵌套类的类 - 但如果您愿意,它们可以是 3 个单独的类。

    POJO 是:

    import com.google.gson.annotations.SerializedName;
    
    public class NestingPojo {
    
        @SerializedName("example1")
        private Example1 example1;
    
        public static class Example1 {
    
            @SerializedName("example2")
            private Example2 example2;
    
            public static class Example2 {
    
                @SerializedName("example3")
                private Integer example3;
    
                public Integer getExample3() {
                    return example3;
                }
    
                public void setExample3(Integer example3) {
                    this.example3 = example3;
                }
    
            }
    
            public Example2 getExample2() {
                return example2;
            }
    
            public void setExample2(Example2 example2) {
                this.example2 = example2;
            }
    
        }
    
        public Example1 getExample1() {
            return example1;
        }
    
        public void setExample1(Example1 example1) {
            this.example1 = example1;
        }
    
    }
    

    严格来说,这种情况下不需要注解,因为 POJO 使用的字段名称与所需的 JSON 名称匹配。

    我们可以按如下方式生成 JSON:

    NestingPojo nestingPojo = new NestingPojo();
    NestingPojo.Example1 example1 = new NestingPojo.Example1();
    nestingPojo.setExample1(example1);
    NestingPojo.Example1.Example2 example2 = new NestingPojo.Example1.Example2();
    example2.setExample3(4);
    example1.setExample2(example2);
                    
    String s = new Gson().toJson(nestingPojo);
    System.out.println(s);
    

    这会生成与第一个示例相同的 JSON 输出。

    在这两种情况下,公共线程都在构建与预期 JSON 输出的层次结构相对应的 Java 对象。

    对于更复杂的示例,第一种方法很快就会变得笨拙。在我看来,第二种方法具有更大的灵活性,因为您正在使用定制类。

    这两种方法都不使用JsonObject。对此类任务使用 Java 对象只是我的偏好。

    更新

    如果JsonObject 是必需的或首选的,这里是一个示例:

    JsonObject json3 = new JsonObject();
    json3.addProperty("example3", 4);
    JsonObject json2 = new JsonObject();
    json2.add("example2", json3);
    JsonObject json1 = new JsonObject();
    json1.add("example1", json2);
    System.out.println(new Gson().toJson(json1));
    

    这会从最里面的对象开始构建嵌套元素。

    更新 2

    可以按如下方式将数据写入文件 - 在本例中,我使用上面的 ex1 对象(嵌套映射):

    Gson gson = new GsonBuilder().setPrettyPrinting().create();
    try ( FileWriter fw = new FileWriter("c:/tmp/ex1.json")) {
        gson.toJson(ex1, fw);
    } catch (IOException ex) {
        // handle the exception here
    }
    

    在这种情况下,我使用了GsonBuilder,因此我可以指定“漂亮打印”选项(您不需要,但很有帮助)。

    这将创建一个包含以下格式化 JSON 的文件:

    {
      "example1": {
        "example2": {
          "example3": 4
        }
      }
    }
    

    【讨论】:

    • 使用第一种方法如何将其保存到文件中?
    • 示例添加到答案的末尾。
    猜你喜欢
    • 1970-01-01
    • 2018-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-07
    相关资源
    最近更新 更多