【问题标题】:Parsing multi value type Json array with Gson用Gson解析多值类型Json数组
【发布时间】:2016-05-17 15:57:42
【问题描述】:

我发现使用 Gson 解析有些 Json(显示的片段)很尴尬。我可以解析其余的 json。我阅读下面的 json 片段的方式是,我有一个名为 arguments 的数组,其中包含一个对象类型、另一个数组类型和一个字符串类型。我无法更改 Json。

有人对如何使用 Gson 解析这个有任何想法吗?

"arguments": [
    {
        "codes": [
            "memberRequest.email",
            "email"
        ],
        "arguments": null,
        "defaultMessage": "email",
        "code": "email"
    },
    [],
    ".*"
]

【问题讨论】:

  • 我对 GSON 不熟悉,所以这个问题肯定有一些我不明白的地方,但是有效的 JSON 是有效的 JSON——任何兼容的解析器都应该解析它。 (另外,FWIW,你发布的不是 JSON,而是一些 JSON 的摘录)
  • 是的,你是对的。这是一个节选。我会更新问题以反映这一点。我试图想象一个可能代表这个 json 的 java 对象,因为 gson 可以使用这样的对象将 json 参数映射到。但是,java 不支持多类型数组,这些类型除了 Object 之外没有共同的父对象,问题就出在这里(我认为)——但这一定很常见,必须有解决方案。

标签: json gson


【解决方案1】:

这取决于您希望在您的 java 表示中具有什么数据结构。您可以选择 3 个选项:

选项 1 ListList<Object>(实际上 Objects 将是 LinkedHashMapStringArrayList

new Gson().fromJson(JSON, ParentPOJO.class);

private static class ParentPOJO{
   public List<Object> arguments;
}

选项 2 自定义 MyListClassMyListClass 的自定义反序列化器 MyListClass extends ArrayList 这样您可以控制反序列化并为您的对象选择适当的数据类型。这将为您提供包含MyClassArrayListStringMyListClass extends ArrayList。演示如下。

public static void main(String[] args) {
    Gson gson = new GsonBuilder().registerTypeAdapter(MyListClass.class, new CustomDeserializer()).create();
    map = gson.fromJson(JSON, ParentPOJO.class);
}

private static class ParentPOJO{
    public MyListClass arguments;
}

private static class MyListClass extends ArrayList{}

private static class CustomDeserializer implements JsonDeserializer{

    @Override
    public Object deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        MyListClass list = null;
        if (json.isJsonArray()){
             list  = new MyListClass();
            JsonArray array = json.getAsJsonArray();

            for(int i = 0; i< array.size();i++){
                Object next = parseNext(array.get(i),context);
                list.add(next);
            }
        }

        return list;
    }
    private Object parseNext(JsonElement json, JsonDeserializationContext context){
        if (json.isJsonArray()){
            return context.deserialize(json, Object.class);//can change object type if you know it
        }else if(json.isJsonPrimitive()){
            return json.getAsJsonPrimitive().getAsString();
        }else if(json.isJsonObject()){
            return context.deserialize(json, MyClass.class);
        }
        return null;
    }
}

public class MyClass {
    @SerializedName("codes")
    private List<String> codes = new ArrayList<String>();
    @SerializedName("arguments")
    private Object arguments;
    @SerializedName("defaultMessage")
    private String defaultMessage;
    @SerializedName("code")
    private String code;
}

选项 3 几乎完全相同,但 MyPOJOClass 而不是 MyListClass 只需更改反序列化器,将字段添加到您的 MyPOJOClass 并将 json 数组映射到反序列化器中的 pojo 字段。如果您选择自定义 MyPOJOClass 的 3-d 选项,还必须创建自定义序列化程序

如果你的 json 数组中有多个相同类型的对象,你将不得不想出某种算法来在反序列化器中解析它们。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-12
    相关资源
    最近更新 更多