かなり複雑なJSONドキュメントのセットをジャクソンとデシリアライズしたいと思っています。継承を処理するために、カスタムデシリアライザを実装しました。継承を処理する複数のカスタムジャクソンデシリアライザを記述するための正しい方法
correktクラスを選択するには、次のノードのプロパティをチェックする必要があります。したがって、ツリーを読み、プロパティをチェックし、正しいクラスを選択します。
その後、私はmapper.readerFor(targetClass).readValue(rootNode)
経由でJSONを読んでいます。ここまではすべてが大丈夫です。
しかし、mapper.readerFor(...)
を使用すると、次のシリアライザは、ObjectMapper
の代わりにObjectReader
インスタンスを取得します。しかし、私は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スキーマ)と一致する必要があります。 2番目の理由は、ルートノードで特定のフィールドとその値をチェックするだけで、ターゲットクラスを判別できるということです。私はあなたにアップフォートをくれました。 – Oliver
Hmmm、区別するためのフィールド値が1つもないので、 "$ ref"フィールドと "in"フィールドを組み合わせなければなりません。 – Wheezil