我想用Jackson反序列化一組相當複雜的JSON文檔。爲了處理繼承,我實現了一些自定義的反序列化器。編寫多個自定義Jackson反串行器來處理繼承的正確方法
要選擇correkt類,我必須檢查下一個節點的屬性。因此,我閱讀樹,檢查屬性並選擇正確的類。
之後,我通過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值。他們必須匹配他們的模式(JSON模式)。第二個原因是,如果我檢查根節點的特定字段及其值,我只能確定目標類。我給你一個upvote。 – Oliver
嗯,我看你沒有一個字段值來區分,你必須結合「$ ref」和「in」字段。 – Wheezil