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