反序列化为动态Java类型

反序列化为动态Java类型,java,json,gson,deserialization,Java,Json,Gson,Deserialization,我今天的问题是我有这种JSON, 使用对象数组,每个对象具有 两个属性:类型和值 [{ “类型”:“布尔值”, “值”:false }, { “类型”:“字符串[]”, “价值”:[“一”、“二”、“三”] }] 如您所见,值类取决于类型。 我可能有一个类型:MyClass,而值是一个复杂的对象 我希望能够反序列化这个数组(并将其序列化回来) (之后输入JSON) 我开始查看图书馆,但我随时可能改变。 据我所知,我只知道一种方法: 公共类MyExtractor实现JsonDeserialize

我今天的问题是我有这种JSON, 使用对象数组,每个对象具有 两个属性:
类型

[{
“类型”:“布尔值”,
“值”:false
}, {
“类型”:“字符串[]”,
“价值”:[“一”、“二”、“三”]
}]
如您所见,
类取决于
类型
。 我可能有一个
类型:MyClass
,而
是一个复杂的对象

我希望能够反序列化这个数组(并将其序列化回来) (之后输入JSON)

我开始查看图书馆,但我随时可能改变。 据我所知,我只知道一种方法:

公共类MyExtractor实现JsonDeserializer{
@凌驾
公共对象反序列化(JsonElement元素,类型jtype,
JsonDeserializationContext(jdc)引发JsonParseException{
//元素是一个对象
JsonObject obj=elem.getAsJsonObject();
String type=obj.get(“type”).getAsString();
//根据“类型”属性返回不同类型的对象
开关(类型){
案例“布尔”:
Boolean bool=obj.get(“value”).getAsBoolean();
返回布尔;
大小写“String[]”:
JsonArray data=obj.get(“value”).getAsJsonArray();
列表=新的ArrayList();
对于(JsonElement项:数据){
添加(item.getAsString());
}
退货清单;
}
}
}
在这里,我添加了代码,将每个
类型
与其相应的类相关联。 这可能会如我所愿,但有更好的方法吗? 这一个最终需要相当多的模板

此外,反序列化的项被强制转换到
对象中
,因此我不需要这样做 无需读取其
getClass()
即可访问其方法,并且 把它们扔回去,我不能从中受益


是否有不同方法解决此问题的库?

如果您可以将原始json更改为:

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

您只需将其反序列化为

String jsonString = ...
Object[] result = new Gson().fromJson(jsonString, Object[].class);
对于每种标准类型(
String
Boolean
Integer
…),它都能很好地工作,对于自定义类,它将创建一个
映射


例如,如果
jsonString
包含内容

["testString", false, {"name":"Davide", "surname":"Marino"}]
它将生成具有以下内容的对象数组:

  • 字符串
    测试字符串位于第一个位置
  • 第二个位置的
    布尔值
    为false
  • 属性name(值Davide)和姓氏(值Marino)位于第三位的
    Map

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

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


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

能够根据特定字段的存在或值进行反序列化。自述文件中的示例几乎正是您想要的

在本例中,您必须创建两个规则,根据
type
的值区分反序列化:

DynamicObjectDeserializer deserializer = new DynamicObjectDeserializer();

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

关于这个

还有更多信息,你可以试着看一下。你能更改json吗?@davidorenzomarino是的,我可以访问生成和使用这个json的JavaScript。理论上我可以用它做任何事。在JS中,将所有对象放在一个数组中很方便,但这可能会改变(在JS中合并多个数组非常容易)。我想这会使反序列化更容易。目前,“type”属性在unique数组中是相关的,因为有4个不同的“复杂类”具有自定义属性和行为。
DynamicObjectDeserializer deserializer = new DynamicObjectDeserializer();

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