0

我正在使用 GSON 反序列化一些 JSON 文件。这是我编写的反序列化方法,我读取了 JSON 文件并将整个内容存储为我传递给该方法的字符串。此方法成功地适用于与该项目相关的 5 个 JSON 文件中的 4 个。

protected ArrayList<Entry> deserialize(String json) throws Exception
{
    ArrayList<Entry> list = new ArrayList<Entry>( );


    JsonParser parser = new JsonParser();

    JsonArray jarray = (JsonArray) parser.parse(json);

    for (int i = 0; i < jarray.size(); i++)
    {

        // Parse out the brand
        JsonObject jentry = (JsonObject) jarray.get(i);

        JsonPrimitive jbrand = jentry.getAsJsonPrimitive("brand");

        String className = jbrand.getAsString();

        Entry entry = (Entry) gson.fromJson(jentry, Class.forName(className));

        list.add(entry);
    }

    return list;
}

这是我解析并放入字符串的 JSON 文件,有几个对象绑定到“jentry”,但我只包含一个。如果它看起来很奇怪,可能是因为我一直在使用 firefox 插件来查看 JSON 文件,并且我从该插件中复制/粘贴。

[

*
  -
  {
      o pattern: "3 5 * * 1-5"
      o starts: 1288249260913
      o ends: 1291125660913
      o skipHolidays: false
      o lastFired: 1289988180395
      o
        -
        template: {
            + location: ""
            + damageCause: ""
            + signed: false
            + signedBy: ""
            + approvedBy: "Ralph"
            + requestedBy: "Ralph"
            + estHours: 0
            + actHours: 0
            + chargeTo: ""
            + priority: "ROUTINE"
            + reason: ""
            + materials: ""
            + serviceId: 1
            + descr: "HELP WITH LEAVES,BLOW LEAVES IN YOUR AREA NEAR DRAINS Check for garbage. [sp] Mow and weedeat where needed in your area. [sp] Work on leaves where needed. [wi]"
            + comments: [ ]
            + futureId: 3
            + inventoryId: -1
            +
              -
              trail: [
                  #
                    -
                    {
                        * stamp: 1288026816857
                        * status: "OPEN"
                        * byId: 2
                    }
                  #
                    -
                    {
                        * stamp: 1288026889374
                        * status: "DISPATCHED"
                        * byId: 2
                    }
                  #
                    -
                    {
                        * stamp: 1288194095170
                        * status: "DISPATCHED"
                        * byId: 2
                    }
                  #
                    -
                    {
                        * stamp: 1288287964481
                        * status: "DISPATCHED"
                        * byId: 2
                    }
                  #
                    -
                    {
                        * stamp: 1288785076532
                        * status: "DISPATCHED"
                        * byId: 2
                    }
                  #
                    -
                    {
                        * stamp: 1288797119525
                        * status: "DISPATCHED"
                        * byId: 2
                    }
                  #
                    -
                    {
                        * stamp: 1289307416921
                        * status: "DISPATCHED"
                        * byId: 2
                    }
                  #
                    -
                    {
                        * stamp: 1289308339165
                        * status: "DISPATCHED"
                        * byId: 2
                    }
                  #
                    -
                    {
                        * stamp: 1289834523635
                        * status: "DISPATCHED"
                        * byId: 2
                    }
                  #
                    -
                    {
                        * stamp: 1289847660913
                        * status: "DISPATCHED"
                        * byId: 2
                    }
              ]
            + requestDate: 1289329260913
            + assignedDate: 1288029660912
            + supplies: [ ]
            + id: 3
            + updateDate: 1289847660913
            + createUserId: 2
            + updateUserId: 2
            + createDate: 1288026816857
            + brand: "org.workplicity.marist.grounds.GroundsRequest"
        }
      o workSlateId: 16
      o serviceId: 1
      o enabled: false
      o id: 3
      o updateDate: 1291235385719
      o createUserId: 2
      o updateUserId: 2
      o createDate: 1288026889373
      o brand: "org.workplicity.entry.event.Weekdays"
  }

问题是当 GSON 转回 JSON(序列化?)时,它缺少一些字段。这是输出,相关的缺失行是“模板:”下方和“服务ID:”上方的所有内容,我将继续并再次包含整个对象。

[

*
  -
  {
      o pattern: "3 5 * * 1-5"
      o starts: 1288249260913
      o ends: 1291125660913
      o skipHolidays: false
      o lastFired: 1289988180395
      o
        -
        template: {
            + serviceId: 1
            + descr: "HELP WITH LEAVES,BLOW LEAVES IN YOUR AREA NEAR DRAINS Check for garbage. [sp] Mow and weedeat where needed in your area. [sp] Work on leaves where needed. [wi]"
            + comments: [ ]
            + futureId: 3
            + inventoryId: -1
            +
              -
              trail: [
                  #
                    -
                    {
                        * stamp: 1288026816857
                        * status: "OPEN"
                        * byId: 2
                    }
                  #
                    -
                    {
                        * stamp: 1288026889374
                        * status: "DISPATCHED"
                        * byId: 2
                    }
                  #
                    -
                    {
                        * stamp: 1288194095170
                        * status: "DISPATCHED"
                        * byId: 2
                    }
                  #
                    -
                    {
                        * stamp: 1288287964481
                        * status: "DISPATCHED"
                        * byId: 2
                    }
                  #
                    -
                    {
                        * stamp: 1288785076532
                        * status: "DISPATCHED"
                        * byId: 2
                    }
                  #
                    -
                    {
                        * stamp: 1288797119525
                        * status: "DISPATCHED"
                        * byId: 2
                    }
                  #
                    -
                    {
                        * stamp: 1289307416921
                        * status: "DISPATCHED"
                        * byId: 2
                    }
                  #
                    -
                    {
                        * stamp: 1289308339165
                        * status: "DISPATCHED"
                        * byId: 2
                    }
                  #
                    -
                    {
                        * stamp: 1289834523635
                        * status: "DISPATCHED"
                        * byId: 2
                    }
                  #
                    -
                    {
                        * stamp: 1289847660913
                        * status: "DISPATCHED"
                        * byId: 2
                    }
              ]
            + requestDate: 1289329260913
            + assignedDate: 1288029660912
            + supplies: [ ]
            + id: 3
            + updateDate: 1289847660913
            + createUserId: 2
            + updateUserId: 2
            + createDate: 1288026816857
            + brand: "org.workplicity.marist.grounds.GroundsRequest"
        }
      o workSlateId: 16
      o serviceId: 1
      o enabled: false
      o id: 3
      o updateDate: 1299694066807
      o createUserId: 2
      o updateUserId: 2
      o createDate: 1288026889373
      o brand: "org.workplicity.entry.event.Weekdays"
  }

JSON 文件中的每个对象都会发生这种情况。NetBeans 中的调试显示 JsonObject 'jentry' 有一个哈希表,其中包含 JSON 字符串中每个数据成员的对应键值对;并且“模板”作为哈希表存储在这个哈希表中,这可能是也可能不是我真的无法找出的问题。

现在,当我最初在问题 JSON 文件上运行此方法时,我在这一行遇到了异常:

Entry entry = (Entry) gson.fromJson(jentry, Class.forName(className));

问题是与此特定 JSON 文件相关的特定类没有无参数构造函数,因此我必须向 GSON 构建器注册一些 InstanceCreators,如下所示:

gsonBuilder.registerTypeAdapter(Weekdays.class, new WeekdaysInstanceCreator());
gsonBuilder.registerTypeAdapter(Once.class, new OnceInstanceCreator());

在我这样做之后,异常停止被抛出并且一切似乎都工作了,当然减去了丢失的字段。

所以这就是我所在的地方,我真的不知道出了什么问题。非常感谢任何帮助。

4

3 回答 3

2

当 Gson 删除 JSON 中存在的字段时,通常是因为您要反序列化的类未定义该字段。如果您使用基类类型对其进行反序列化,则可能会发生这种情况。您能否检查 org.workplicity.marist.grounds.GroundRequest 是否包含您所指的字段?

于 2011-03-23T18:10:32.353 回答
0

NetBeans 中的调试显示 JsonObject 'jentry' 有一个哈希表,其中包含 JSON 字符串中每个数据成员的对应键值对;并且“模板”作为哈希表存储在这个哈希表中,这可能是也可能不是我真的无法找出的问题。

这很正常。Gson 最初将 JSON 对象读入 a JsonObject,其中 JSON 元素名称和值存储在 a 中LinkedHashMap。因此,如果 JSON 结构在对象中包含一个对象,那么 Gson 将 JSON 读取到的初始结构将是 aJsonObject和 a LinkedHashMap,其中一个条目将具有另一个JsonObject带有 a的值LinkedHashMap

原帖并没有清楚地描述地图中的内容JsonObjects意外缺失。它只是描述了在序列化反序列化数据后发现一些内容丢失。由于没有提供足够的信息来重现问题,人们只能猜测问题可能是什么。并且 inder 的猜测看起来和任何猜测一样好。我看不出任何表明 Gson 有缺陷的地方。

关于题名“JSON deserialization using GSON skips data members from a hashmap inside a hashmap”的题名的具体表述,从题的剩余内容来看,我认为原题实际上并不意味着目标Java结构是一个map地图内。如果目标 Java 结构是地图中的地图,那么我无法重现 Gson 神秘地跳过某些字段的场景,前提是 JSON 元素正确绑定到 Java 字段,并且对Gson 问题 325的处理是提供(带有自定义反序列化)。

于 2011-06-18T22:27:04.267 回答
0

请尝试下载最新版本的 Gson,1.7。它包含许多可能对您有所帮助的新功能。请参阅http://groups.google.com/group/google-gson/browse_thread/thread/6272c9be58676e47#

一方面,不再需要 Instance Creator,因为 Gson 能够为任何类实例自动分配堆空间,而无需使用默认构造函数或实例创建者。

至于字段的跳过,默认情况下,Gson 会跳过“静态”、“瞬态”或“内部类”的字段。

于 2011-04-13T08:21:15.923 回答