Gson - 如何使用 gson 通过更改键反序列化嵌套对象?

问题描述 投票:0回答:1

我试图解析的示例 json 是:

[
    {
        "id": "123",
        "a*": {
            "b*": {
                "prio": {
                    "d*": {
                        "id": "234",
                        "name": "test"
                    },
                    "d1*": {
                        "id": "678",
                        "name": "test1"
                    }
                }
            },
            "b1*": {
                "prio": {
                    "d2*": {
                        "id": "234",
                        "name": "test4"
                    }
                },
                "prio": {
                    "d3*": {
                        "id": "234",
                        "name": "test3"
                    }
                }
            }
        },
        "a1*": {
            "b2*": {
                "prio": {
                    "d5*": {
                        "id": "5435",
                        "name": "test2"
                    },
                    "d6*": {
                        "id": "675435438",
                        "name": "test15"
                    }
                }
            }
        }
    },
    {
        "id": "345",
        "f*": {
            "g*": {
                "prio": {
                    "i*": {
                        "id": "5435",
                        "name": "test2"
                    }
                }
            }
        }
    },
    {
        "id": "342343"
    }
]

出于解释的目的,带有星号的那些在不同的 json 文件中总是有变化的键,而实际的 json 文件的键中可能有也可能没有星号。嵌套数量不会比显示的嵌套更深,但有些可能不那么深。

prio
将始终处于相同的深度级别,我需要除
prio
之外的所有键名。

如何用 gson 解析这个 json?任何帮助表示赞赏。

我在尝试什么(改名):


@Getter
@Setter
public class PolicyObject {
    private String id;
    private Map<String, First> firstMap;

    @Getter
    @Setter
    public class First {
        private Map<String, Second> secondMap;
    }

    @Getter
    @Setter
    public class Second {
        private List<Third> prio;
    }

    @Getter
    @Setter
    public class Third {
        private String id;
        private String name;
    }
}
public class mainClass {
    public void main(InputStreamReader file) {
        Type typeOfT = TypeToken.getParameterized(PolicyObject.class, clazz).getType();
        List<PolicyObject> policies = gson.fromJson(file, typeOfT);
    }
}

firstMap 结果为空。我使用 gson 的原因是因为我已经将它用于同一包中具有更简单格式的其他 json 文件。

java gson
1个回答
0
投票

firstMap 结果为空。

那是因为你没有任何 json 元素名称“firstMap”。 GSON(和大多数 JSON 解析器)通过将 json 元素名称映射到类字段来工作。如果您没有一致的元素名称,那么您需要一个映射来表示具有可变元素名称的整个对象。

首先看起来你在顶层有一个对象数组,所以确保你要求 GSON 解析一个数组对象。像这样的东西:

ItemType[] items = gson.fromJson(inputString, ItemType[].class)

那么什么是“ItemType” - 数组中的每个项目都有一个“id”但随后是可变键,所以你不能使用你的

PolicyObject
类,你需要一个String到次要项目类型的映射:

Map<String, SecondaryType>[] items =
    gson.fromJson(inputString, Map<String, SecondaryType>[].class)

那么什么是“SecondaryType”?同样,所有键都是可变的,因此您再次需要一张地图:

Map<String, Map<String, ThirdType>[] items =
    gson.fromJson(inputString, Map<String, Map<String, ThirdType[].class)

那么什么是“ThirdType”?好吧,在这一点上,您似乎知道您将拥有一个名为

"prio"
的键,因此您可以定义一个命名良好的类:

public class ThirdType {
    public Prio prio
}

那么什么是“Prio”?同样,它似乎包含一个可变的键列表,所以我们实际上回到了通用映射:

public class ThirdType {
    public Map<String, FourthType> prio
}

那么什么是“FourthType”呢?好吧,这看起来像是一致的“id”和“name”:

public class FourthType {
    public String id;
    public String name;
}

有了这些定义,我们回到:

Map<String, Map<String, ThirdType>[] items =
    gson.fromJson(inputString, Map<String, Map<String, ThirdType[].class)

您可以使用顶级地图的类来清理它:

public class MyObject extends Map<String, Map<String, ThirdType>> { }

然后你可以做这样的事情:

MyObject[] items = gson.fromJson(inputString, MyObject[].class)

免责声明:我不知道这是否会真正编译,但我认为它应该让你走上正轨。

© www.soinside.com 2019 - 2024. All rights reserved.