- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我将分别调用两种不同类型。我想根据业务需求进行反序列化或序列化。
一种类型的json:
{
"type": "foo",
"data": [{
"someCommonProperty": "common property",
"fooProperty": "foo specific property"
},{
"someCommonProperty": "common property1",
"fooProperty": "foo specific property1"
}]
}
另一种json:
{
"type": "bar",
"data": [{
"someCommonProperty": "common property",
"barProperty": "bar specific property",
"type": "type1"
},{
"someCommonProperty": "common property1",
"barProperty": "bar specific property1",
"type": "type1"
}]
}
我有如下类(class)
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
}
当我尝试如下反序列化时,在将 java 对象写为 json 时得到空字符串。
ObjectMapper mapper = new ObjectMapper();
Parent parent = mapper.readValue(json, Parent.class);
我收到这个错误:
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])
最佳答案
如果您有权访问 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
}
然后,无需注释 Foo
、Bar
和 Parent
:只要您的子类具有不同的属性名称,所有内容都会自动实例化. type
json 属性也变得无用。
(如果你使用的是SpringBoot,你可以设置jackson-bom.version
属性来升级spring boot中的jackson)
JsonTypeInfo.As.EXTERNAL_PROPERTY
的 javadoc 说:另请注意,此机制不能用于容器值(数组、集合...
。我相信这是你的问题:你正在将它应用于 List
。
如果您无法修改任何 Foo/Barr/AbstractData 类,经典方法是使用自定义反序列化器。在 Parent
类上:
@JsonDeserialize(contentUsing = FooBarDeserializer.class)
private List<AbstractData> data;
反序列化器:
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);
}
}
如果您找到使用您的 Parent.type
的解决方案,请分享,我很感兴趣。
关于json - Jackson 多态反序列化和序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66555519/
我来自 Asp.Net 世界,试图理解 Angular State 的含义。 什么是 Angular 状态?它类似于Asp.Net中的ascx组件吗?是子页面吗?它类似于工作流程状态吗? 我听到很多人
我一直在寻找 3 态拨动开关,但运气不佳。 基本上我需要一个具有以下状态的开关: |开 |不适用 |关 | slider 默认从中间开始,一旦用户向左或向右滑动,就无法回到N/A(未回答)状态。 有人
我是一名优秀的程序员,十分优秀!