反序列化为动态Java类型

时间:2017-11-06 16:07:25

标签: java json gson deserialization

我今天的问题是我有这种JSON, 一个对象数组,每个对象都有 两个属性:value[{ "type": "Boolean", "value": false }, { "type": "String[]", "value": ["one", "two", "three"] }]

value

如您所见,type课程取决于type: MyClass。 我可能有一个valuepublic 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; } } } 是一个复杂的对象。

我希望能够反序列化此数组(并将其序列化 之后进入JSON。)

我开始调查Gson库,但我可能随时更改。 从我所读到的,我只知道一种方式:

type

在这里,我添加代码将每个Object与其正确的类相关联。 这可能会按照我的意愿运作,但有更好的方法吗? 这个最终需要相当多的模板。

此外,反序列化的项目会被投射到getClass()中,所以我不知道 无需阅读child_set_property()GtkContainer即可访问他们的方法 把它们扔掉,我无法从overloading中受益。

图书馆有不同的解决方法吗?

3 个答案:

答案 0 :(得分:1)

如果你可以改变原来的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数组:

  • 第一个位置的String testString
  • Boolean false 位于第二位
  • Map属性名称(值 Davide )和姓氏(值 Marino )在第三位

如果您不需要处理现有的java类,但是您有3 4个自定义类,则可以使用polimorphic反序列化。

基本上,您需要创建自定义接口(或基类)并实现(或扩展)它。 要查看更完整的示例,请参阅

的已接受答案

Gson serialize a list of polymorphic objects

答案 1 :(得分:1)

您可以尝试使用jolt json变换器,然后使用其中一个标准映射器(Jackson,gson等)

答案 2 :(得分:0)

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的更多信息