【问题标题】:Using GSON to parse Json into a JAVA Object where the Json Elements may vary使用 GSON 将 Json 解析为 Json 元素可能不同的 JAVA 对象
【发布时间】:2017-12-11 14:00:10
【问题描述】:

我正在尝试使用 GSON 将 JSON .txt 文件解析为 JAVA 对象。 JSON 文件的结构如下:

    {
        "event0" : {
        "a" : "abc",
        "b" : "def"
        },

        "event1" : {
        "a" : "ghi",
        "b" : "jkl",
        "c" : "mno"
        }
    }

我已将文本文件读入一个名为 dataStr 的字符串。我想使用 fromJson 方法将事件捕获到以下 JAVA 类中:

public class Event {
    private String a;
    private String b;
    private String c;

    public Event() {}

}

问题是 JSON 在某些元素中可能有一个额外的字段“c”。我想将所有事件解析为 Event 类对象,对于没有“c”字段的情况,我想在我的对象中将其设为 null 或零。事先不知道哪些元素将具有“c”字段。

具体来说,我无法弄清楚如何处理某些 JSON 元素中的一个额外字段。我想做一些类似的事情:

Gson gson = new Gson();
ArrayList<Event> events = gson.fromJson(dataStr, Event.class);

但我首先遇到了问题,如何迭代 Json 文件中的事件,其次,如何将一些偶尔丢失的字段处理到同一个 Event 对象中。我真的很感激朝着正确的方向踢球。谢谢大家。

我对 JSON 解析相当陌生,可能在以下答案中遗漏了一些内容:

Using Gson to convert Json into Java Object

Mapping JSON into POJO using Gson

Using gson to parse json to java object

Parse JSON into a java object

How to parse a json file into a java POJO class using GSON

【问题讨论】:

  • 您的 JSON 看起来不正确,您能描述一下您要查找的数据模型吗?可能值为 A、B 和 C 的事件数组?
  • 修复了 JSON。是的,一系列事件,肯定有 A 和 B 的值,可能还有 C。

标签: java json parsing gson


【解决方案1】:

试试下面的代码 sn-p:

Gson gson = new Gson();
ArrayList<Event> events = gson.fromJson(dataStr, new TypeToken<ArrayList<Event>>(){}.getType());

在Gson的源码中有很清楚的解释

【讨论】:

    【解决方案2】:

    首先我相信你的 JSON 应该是这样的:

    {
      "events": [
        {
          "name": "event0",
          "a": "abc",
          "b": "def"
        },
        {
          "name": "event1",
          "a": "abc",
          "b": "def",
          "c": "mno"
        }
      ]
    }
    

    您的模型需要两个类:

    public List<Event> events = null;
    
    public class Event {
    public String name;
    public String a;
    public String b;
    public String c;
    
    }
    

    然后是 GSON

    Events events = gson.fromJson(jsonData, Events.class);
    

    我还建议始终使用 JSON 的在线验证器,以便在针对 JSON 结构进行编码之前确定您的 JSON 结构是正确的。 https://jsonlint.com/ 或者用于格式化 JSON: http://jsonprettyprint.com/

    此外,该网站还可以从 JSON 模式或使用示例文件为您创建 Java 类。 http://www.jsonschema2pojo.org/

    【讨论】:

    • 感谢您指出这个错误。编辑了原始帖子。我已经验证了我的 json 文件,但在此处发布了一个更简单的结构时打错了字。 PS。您如何编辑原始帖子?
    • 应该是左下角的编辑选项。我仍然相信你最好创建一个与我建议的类似的解决方案来获得更强类型的对象,而不是使用地图
    • 我同意 JSON 的结构。但是,我只是想从这些先前生成的(错误的)JSON 文本文件中快速获取数据。我的主应用程序现在使用数据库来存储数据,我不想花太多精力从文本文件中读取。谢谢
    【解决方案3】:

    我不确定我是否正确理解了您的问题。根据我的理解,您正在尝试使用 java 类中不可用的额外字段转换 json 对象。坦率地说,我不明白您为什么要这样做,或者是否可以开始。您可以通过将 json 转换为 Map 来解决问题。

    Map map = gson.fromJson(jsonString, Map.class);

    【讨论】:

    • 也可以指定泛型:Map&lt;String, Event&gt; map = gson.fromJson(jsonString, new TypeToken&lt;Map&lt;String, Event&gt;&gt;() {}.getType())
    • 同意。这更简单,使用 TypeToken 也是一个可行的选择。
    • 感谢您的回复。并不是说 java 类中没有额外的字段。如前所述,我的 java 类 Event 具有该属性。然而,JSON 由一系列事件组成,其中一些具有该字段,而另一些则没有。对于那些没有的,我希望将 java 对象属性设置为 null。我觉得它应该像@Manuel Gozzi 的回答一样简单,但是我在代码上遇到了问题: ArrayList events = gson.fromJson(dataStr, Event.class);想知道这是否是从 JSON 中填充列表的正确方法。
    • 转换为地图有帮助。然后我可以遍历 Map 并填充我的 Event 对象。谢谢。
    【解决方案4】:

    Gson 会自动为您执行此操作。

    因此,如果您有一个包含 3 个字段(“a”、“b”和“c”)的类“Alpha”,并且您尝试处理具有 2 个名称与 Alpha 的“a”匹配的名称的 json 对象"和"b",Gson会用json文件的值填充"a"和"b","c"会自动设置为null。

    所以,在你的情况下,如果你这样写:

    ArrayList<Event> events = gson.fromJson(dataStr, Event.class);
    

    在您的 json 中,有只有 2 个字段的事件(与任何事件的类字段匹配)和所有字段设置的事件,您将获得一个没有错误的事件列表。也许你会得到一些字段为空,但代码会起作用。

    希望对你有所帮助!如果您愿意,请询问更多信息!

    编辑

    请注意,您的 json 文件不必是 .txt 而是 .json!

    【讨论】:

    • 感谢您的回复。这是我尝试执行此操作时遇到的错误: ArrayList events = gson.fromJson(dataStr, Event.class);错误:不兼容的类型:推理变量 T 具有不兼容的边界等式约束:bo.Event 上限:java.util.ArrayList,java.lang.Object
    • 文件名可以任意,只要内容是文本格式的合法JSON即可。
    • 是的,同意@StefanE,因为我已经能够将包含有效 JSON 的 .txt 文件读入名为 dataStr 的字符串中。所以实际文件不是问题。
    • 我理解错误。请注意,Event 类和ArrayList 类是两个不同的文件。因此,如果您编写ArrayList&lt;Event&gt; events = gson.fromJson(dataStr, Event.class);,Gson 假装读取包含对象事件的.json,而不是对象ArrayList&lt;Event&gt;。尝试将您的代码更改为以下内容:ArrayList&lt;Event&gt; events = gson.fromJson(dataStr, ArrayList.class);。换句话说,您正在创建一个新的 ArrayList,执行一个任务,说您从 json 获得一个事件。实际上,您正在创建一个事件而不是事件的数组列表。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多