我想用 Jackson 反序列化一组相当复杂的 JSON 文档。为了处理继承,我实现了一些自定义反序列化器。
要选择相关类,我必须检查下一个节点的属性。因此,我阅读了树,检查了属性并选择了正确的类。
之后,我通过 mapper.readerFor(targetClass).readValue(rootNode)
读取 JSON。直到这里一切都很好。
但是当我使用 mapper.readerFor(...)
时,下一个调用的序列化程序会获取 ObjectReader
实例而不是 ObjectMapper
。但我需要一个 ObjectMapper
实例。
我怎样才能做得更好?
这是我的反序列化器之一,它导致了我的问题:
public AbstractParametersObject deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
Class<? extends AbstractParametersObject> targetClass = null;
ObjectMapper mapper = (ObjectMapper) p.getCodec();
ObjectNode root =mapper.readTree(p);
boolean isReference = root.has("$ref");
boolean isParameter = root.has("in");
if (isReference) targetClass = ParameterAsReference.class;
else if (isParameter) {
targetClass = Optional.of(root.get("in")).map(JsonNode::asText).map(value -> {
Class<? extends AbstractParametersObject> effectiveClass = null;
switch (value) {
case "body": effectiveClass = BodyParameterObject.class;
break;
case "query": effectiveClass = QueryParameterObject.class;
break;
case "path": effectiveClass = PathParameterObject.class;
break;
case "formData": effectiveClass = FormDataParameterObject.class;
break;
case "header": effectiveClass = HeaderParameterObject.class;
break;
}
return effectiveClass;
}).orElseThrow(() -> new IllegalArgumentException("todo"));
}
AbstractParametersObject parametersObject = mapper.readerFor(targetClass)
.readValue(root);
return parametersObject;
}
最佳答案
这可能比您想象的要容易,尽管在没有看到您的一些 JSON 示例的情况下我无法确定。 Jackson 可以直接处理多态性,无需使用 @JsonTypeInfo 和 @JsonSubTypes 注释的自定义序列化器,只要有一个字段的值指示要创建哪个子类即可。例如,假设我有两个不同的文档,它们共享一些公共(public)字段:
{ "type":"square", "name":"my square", "x":12, "y":34, "size":22 }
{ "type":"rectangle", "name":"my rect", "x":9, "y":11, "width":4, "height":9 }
这可以注释为:
@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, property="type")
@JsonSubTypes({
@Type(name = "square", value = Square.class),
@Type(name = "rectangle", value = Rectangle.class)
})
public abstract class Shape {
public String name;
public int x;
public int y;
}
public class Square extends Shape {
public int size;
}
public class Rectangle extends Shape {
public int width;
public int height;
}
关于java - 编写多个自定义 Jackson 反序列化器来处理继承的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42596275/