use*_*452 3 polymorphism json deserialization
我将两种不同类型的单独调用。我想根据业务需求进行反序列化或序列化。
一种 json 类型:
{
"type": "foo",
"data": [{
"someCommonProperty": "common property",
"fooProperty": "foo specific property"
},{
"someCommonProperty": "common property1",
"fooProperty": "foo specific property1"
}]
}
Run Code Online (Sandbox Code Playgroud)
另一种类型的json:
{
"type": "bar",
"data": [{
"someCommonProperty": "common property",
"barProperty": "bar specific property",
"type": "type1"
},{
"someCommonProperty": "common property1",
"barProperty": "bar specific property1",
"type": "type1"
}]
}
Run Code Online (Sandbox Code Playgroud)
我有如下课程
public class Parent {
private String type;
@JsonTypeInfo(use = Id.NAME, property = "type", include = As.EXTERNAL_PROPERTY)
@JsonSubTypes(value = {
@JsonSubTypes.Type(value = Foo.class, name = "foo"),
@JsonSubTypes.Type(value = Bar.class, name = "bar")
})
private List<AbstractData> data;
// Getters and setters
}
public abstract class AbstractData {
private String someCommonProperty;
// Getters and setters
}
public class Foo extends AbstractData {
private String fooProperty;
// Getters and setters
}
public class Bar extends AbstractData {
private String barProperty;
private String type;
// Getters and setters
}
Run Code Online (Sandbox Code Playgroud)
当我尝试如下反序列化时,我在将 java 对象写为 json 时得到空字符串。
ObjectMapper mapper = new ObjectMapper();
Parent parent = mapper.readValue(json, Parent.class);
Run Code Online (Sandbox Code Playgroud)
我收到此错误:
com.fasterxml.jackson.databind.JsonMappingException: Unexpected token (START_OBJECT), expected START_ARRAY: need JSON Array to contain As.WRAPPER_ARRAY type information for class com.DemoJsonToJavaDeserialize.AbstractData
at [Source: C:<projectpath>\target\classes\foo.json; line: 3, column: 12] (through reference chain: com.DemoJsonToJavaDeserialize.Parent["data"]->java.util.ArrayList[0])
Run Code Online (Sandbox Code Playgroud)
小智 7
如果您有权访问该AbstractData课程,您可能需要使用新的 2.12 Jackson Deduction功能:
@JsonSubTypes(value = {
@JsonSubTypes.Type(value = Foo.class),
@JsonSubTypes.Type(value = Bar.class)
})
@JsonTypeInfo(use = JsonTypeInfo.Id.DEDUCTION)
public abstract class AbstractData {
private String someCommonProperty;
// getters setters
}
Run Code Online (Sandbox Code Playgroud)
然后,无需注释Foo,Bar和Parent:只要您的子类具有不同的属性名称,所有内容都会自动实例化。typejson 属性也变得毫无用处。
(如果使用SpringBoot,可以jackson-bom.version在spring boot内部设置属性升级jackson)
javadoc说:。 我相信这是您的问题:您将其应用于.JsonTypeInfo.As.EXTERNAL_PROPERTYNote also that this mechanism can not be used for container values (arrays, Collections...List
如果您无法修改任何 Foo/Barr/AbstractData 类,经典方法是使用自定义Deserializer。在课堂上Parent:
@JsonDeserialize(contentUsing = FooBarDeserializer.class)
private List<AbstractData> data;
Run Code Online (Sandbox Code Playgroud)
和解串器:
public class FooBarDeserializer extends JsonDeserializer<AbstractData> {
@Override
public AbstractData deserialize(JsonParser jsonParser, DeserializationContext ctxt) throws IOException {
JsonNode node = jsonParser.readValueAsTree();
if(node.has("fooProperty"))
return jsonParser.getCodec().treeToValue(node,Foo.class);
else
return jsonParser.getCodec().treeToValue(node,Bar.class);
}
}
Run Code Online (Sandbox Code Playgroud)
如果您找到了利用您的解决方案Parent.type,请分享,我很感兴趣。
| 归档时间: |
|
| 查看次数: |
3716 次 |
| 最近记录: |