class GeneralObject {
public String objType;
public String commonProp;
public GeneralObject nestedObject;
// map for additional properties, so that I can re-serialize the full object later
public Map<String, JsonNode> additionalFields = new HashMap<>();
@JsonAnyGetter
public Map<String, JsonNode> getAdditionalFields() {
return additionalFields;
}
@JsonAnySetter
public void addAdditionalField(String fieldName, JsonNode value) {
this.additionalFields.put(fieldName, value);
}
}
class SpecialObject extends GeneralObject {
public String specialProp;
}
{
"objType": "someType1",
"commonProp": "example1..."
}
{
"objType": "SPECIAL",
"commonProp": "example2...",
"specialProp": "more example"
}
{
"objType": "someOtherType",
"commonProp": "example3...",
"nestedObject": {
"objType": "SPECIAL",
"commonProp": "example2...",
"specialProp": "more example"
}
}
ObjectMapper mapper = new ObjectMapper();
String objString = "{\"objType\": \"SPECIAL\", \"commonProp\": \"...\", \"specialProp\": \"more example\"}";
GeneralObject genObj = mapper.readValue(objString, GeneralObject.class);
if (genObj.objType.equals("SPECIAL")) {
genObj = mapper.readValue(objString, SpecialObject.class);
}
// Some business-logic: If SPECIAL, then this cast is required to work:
System.out.println(((SpecialObject) genObj).specialProp);
这适用于顶级对象,但不适用于嵌套对象。例如,如果嵌套对象是特殊对象,则仍将其反序列化为公共对象。
我想做的是告诉Jackson:“无论嵌套级别如何,如果ObjType=Special,使用SpecialObject,否则使用GeneralObject”。我研究了多态反序列化,并尝试使用@JSONSubtypes,但无法正确设置该逻辑。如何确保特殊对象被反序列化到适当的类中,即使它们是嵌套的?
我首先尝试从这个要点中获得灵感,我想用自定义的TypeIDResolver
来解决这个问题,但是这个问题不能正确地反序列化ObjType
(请参阅本答案的第一版)。
然后切换到自定义的反序列化器
:
class CustomDeserializer extends StdDeserializer<GeneralObject> {
private static final String SPECIAL = "\"SPECIAL\"";
protected CustomDeserializer() {
super(GeneralObject.class);
}
@Override
public GeneralObject deserialize(JsonParser p, DeserializationContext ctx) throws IOException {
TreeNode node = p.readValueAsTree();
// Select appropriate class based on "resourceType"
TreeNode objTypeNode = node.get("objType");
if (null == objTypeNode) {
throw new JsonParseException(p, "field \"objType\" is missing!");
}
if (!objTypeNode.isValueNode()) {
throw new JsonParseException(p, "field \"objType\" must be a String.");
}
String objType = objTypeNode.toString();
Class<? extends GeneralObject> clazz;
if (objType.equals(SPECIAL)) {
clazz = SpecialObject.class;
} else {
clazz = RecursionStopper.class;
}
return p.getCodec().treeToValue(node, clazz);
}
}
它检查.objtype
的内容,并发出应该用于反序列化的适当(子)类。需要在GeneralObject
上注册反序列化器,例如使用以下注释:
@JsonDeserialize(using = CustomDeserializer.class)
class GeneralObject {
...
}
@JsonDeserialize(using = JsonDeserializer.None.class)
class SpecialObject extends GeneralObject {
public String specialProp;
}
@JsonDeserialize(using = JsonDeserializer.None.class)
class RecursionStopper extends GeneralObject {
// this class intentionally empty
}
ObjectMapper mapper = new ObjectMapper();
String objString = "{\n" +
" \"objType\": \"someObjType\",\n" +
" \"commonProp\": \"example3...\",\n" +
" \"nestedObject\": {\n" +
" \"objType\": \"SPECIAL\",\n" +
" \"commonProp\": \"example2...\",\n" +
" \"specialProp\": \"more example\"\n" +
" }\n" +
"}";
GeneralObject genObj = mapper.readValue(objString, GeneralObject.class);
System.out.println(((SpecialObject) genObj.nestedObject).specialProp);
我正试图找到一种方法来使用jackson的多态反序列化功能,它将基于嵌套在标头/控件对象中的属性反序列化我的对象: JSON 1-类别1: JSON 2-类别2 父类(类似这样的注释) 子类 jackson中是否有现成的功能可以让我进行这种反序列化,或者我遗漏了什么?
但它返回一个id为空且产品为空的对象。当然,我不需要为这个简单的操作编写自定义的吗?
我对对象接口的jackson序列化有问题。 我有课 哪个实现 还有上课 哪个实现 上课 我要和Jackson连载Container得到结果 但事实上我得到了结果 尽管我在映射中指定了点的序列化类型(),但在嵌套对象“point”中具有属性“name”。接口点视图没有方法getName,但结果中存在点的字段“name”。 若我从类容器中的方法getMap中删除注释(),我将得到结果 现在点没有属性"
问题内容: 我从看起来像这样的API获取JSON: 我尝试了几种方法来在c#对象中表示此JSON(太多内容无法在此处列出)。我已经尝试过使用列表和字典,这是我尝试表示它的最新示例: 这是我用来反序列化JSON的方法: 包含和。并且包含,但是是。因此,除了反序列化之外,什么都没有。 它应该很简单,但是由于某种原因我无法弄清楚正确的对象表示形式 问题答案: 要使用,即: 假设项目名称和随响应而变化,并
我认为最好用一个例子来解释。 我有一个想要反序列化的JSON对象,它包含一个接口类型列表以及列表中的类型,但是我不确定如何让反序列化器确定列表中的具体类型: 要反序列化的类型 界面 儿童 我知道如果类型不是<code>List</code>,我可以将类型与<code>JsonSubTypes</code>一起使用,例如: 如果在父类型内,也是如此。但是当类型在类之外时,是否有一种方法可以帮助反序列
问题内容: 我有一个名为的类,该类具有一个作为参数的构造函数: 具有以下属性: 并且是我的应用程序的其他类,并具有以下构造函数: ,并且是的子类。 我想用Gson 反序列化数组,所以我写道: 以定义为: 调试时,实例具有正确的“ MainActivity”作为上下文,而其成员变量的上下文为null。 Gson 使用正确的构造函数创建了对象,但使用默认的无参数构造函数创建了实例。我怎样才能解决这个问