gson 反序列化为动态Java类型

mo49yndu  于 2022-11-06  发布在  Java
关注(0)|答案(3)|浏览(248)

我今天的问题是我有这样的JSON,它有一个对象数组,每个对象有两个属性:typevalue中的一个或多个。

[{
    "type": "Boolean",
    "value": false
}, {
    "type": "String[]",
    "value": ["one", "two", "three"]
}]

正如你所看到的,value类依赖于type。我可能有一个type: MyClass,其中value是一个复杂对象。
我希望能够反序列化这个数组(并在之后将其序列化回JSON)。
我开始研究Gson库,但我可能随时会改变。从我所读到的内容来看,我只知道一种方法:

public class MyExtractor implements JsonDeserializer<Object> {
    @Override
    public Object deserialize(JsonElement elem, Type jtype,
            JsonDeserializationContext jdc) throws JsonParseException {
        // elem is an object
        JsonObject obj = elem.getAsJsonObject();
        String type = obj.get("type").getAsString();
        // Return a different kind of Object depending on the 'type' attr
        switch (type) {
        case "Boolean":
            Boolean bool = obj.get("value").getAsBoolean();
            return bool;
        case "String[]":
            JsonArray data = obj.get("value").getAsJsonArray();
            List<String> list = new ArrayList<String>();
            for (JsonElement item : data) {
                list.add(item.getAsString());
            }
            return list;
        }
    }
}

在这里我添加了一些代码,将每个type与它的类关联起来。这可能会像我希望的那样工作,但是有没有更好的方法呢?这个方法最终需要相当多的模板。
此外,反序列化的项被转换为Object,因此如果不阅读它们的getClass()并将其转换回来,我就无法访问它们的方法,并且我无法从overloading中受益。
是否存在采用不同方法解决问题的图书馆?

e5njpo68

e5njpo681#

如果您可以将原始json从:

[{
    "type": "Boolean",
    "value": false
}, {
    "type": "String[]",
    "value": ["one", "two", "three"]
}]

[false, ["one", "two", "three"]]

您只需将其反序列化为

String jsonString = ...
Object[] result = new Gson().fromJson(jsonString, Object[].class);

这对于每个标准类型(StringBooleanInteger ...)都很有效,对于自定义类,它将创建一个Map
例如,如果jsonString具有内容

["testString", false, {"name":"Davide", "surname":"Marino"}]

它将生成一个Object数组,其中包含:

  • StringtestString位于第一个位置
  • 第二个位置的Booleanfalse
  • Map,属性name(值为Davide)和rename(值为Marino)位于第三位

如果你不需要处理现有的java类,但你有3 4个自定义类,你可以使用多形态反序列化。
基本上,您需要创建一个自定义接口(或基类)并实现(或扩展)它。
Gson serialize a list of polymorphic objects

czq61nw1

czq61nw12#

您可以尝试jolt json变压器,然后使用标准Map器之一(Jackson,gson等)

vfhzx4xs

vfhzx4xs3#

pretius-jddl能够根据特定字段的存在或值进行反序列化。自述文件中的示例几乎完全符合您的要求。
在本例中,您必须创建两个规则,根据type的值来区分反序列化:

DynamicObjectDeserializer deserializer = new DynamicObjectDeserializer();

deserializer.addRule(DeserializationRuleFactory.typeByFieldValue(1, 
    "type", "Boolean", Boolean.class));
deserializer.addRule(DeserializationRuleFactory.typeByFieldValue(1, 
    "type", "String[]", String[].class));

有关此blog post about jddl的更多信息

相关问题