【问题标题】:Gson: deserializing arrays where elements are not of same typeGson:反序列化元素类型不同的数组
【发布时间】:2015-02-14 14:11:09
【问题描述】:

我尝试使用 Gson 库反序列化 json 字符串; 我有以下课程

class Foo {
    int Id;
    String Name;
}

以及下面的json字符串

{response: [123, { id: 1, name: 'qwerty'}, { id: 2, name: 'asdfgh'}, ]}

我尝试反序列化这个字符串

Gson gson = new Gson();         
Foo[] res = gson.fromJson(jsonStr, Foo[].class);

但我失败了,因为这个字符串不包含纯 json 数组,而是包含字段“响应”的对象,即数组。 我的第二个麻烦是响应包含文字“123”,除了 Foo 对象。

我想知道如何避免这些问题?我是否应该手动解析字符串,提取数组的内容,从中删除不必要的文字并将解析结果提供给 fromJson 方法或 有什么方法可以帮助我做的更简单?

【问题讨论】:

  • 没有“纯”JSON 数组这样的东西。 RFC 7159 明确指出,根本没有要求 JSON 数组的成员都必须属于同一类型(更重要的是,您的 JSON 实际上不是合法的 JSON)。
  • 好的,什么是将这个数组变成“纯”(或“合法”)的最简单、最快捷的方法?
  • 读为JsonElement,过滤掉不需要的元素,然后反序列化;这是我会推荐的。另一种解决方案是使用流 API

标签: java json parsing gson


【解决方案1】:

没有与您尝试反序列化的 json 数组兼容的 Java 类型。您应该使用 JsonParser 获取 JsonObject,然后手动处理该 JsonObject。

JsonParser p = new JsonParser();
JsonObject jsonObject = (JsonObject)p.parse(yourJsonString);

然后您可以像这样处理您的 jsonObject:

    List<Foo> foos = new ArrayList<Foo>();
    JsonArray response = jsonObject.getAsJsonArray("response");
    for (int i = 0; i < response.size(); i++) {
        JsonElement el = response.get(i);
        if (el.isJsonObject()) {
            Foo f = new Foo();
            JsonObject o = el.getAsJsonObject();
            int id = o.getAsJsonPrimitive("id").getAsInt();
            String name = o.getAsJsonPrimitive("name").getAsString();
            f.Id = id;
            f.Name = name;      
            foos.add(f);
        }
    }

或者,您可以像这样处理响应 JsonArray:

    List<Foo> foos = new ArrayList<Foo>();
    JsonArray response = jsonObject.getAsJsonArray("response");
    for (int i = 0; i < response.size(); i++) {
        JsonElement el = response.get(i);
        if (el.isJsonObject()) {
            JsonObject o = el.getAsJsonObject();
            Foo f = gson.fromJson(o, Foo.class);
            foos.add(f);
        }
    }

但您需要确保 Foo 类成员名称与 json 属性名称匹配。你的不是因为大写。即你需要改变你的 Foo 类是这样的:

class Foo {
    int id;
    String name;
}

【讨论】:

  • 一般来说,如果您要使用 gson.fromJson(),您需要确保您的类成员名称与 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
相关资源
最近更新 更多