У нас есть класс View
, который служит вариантом: он может содержать просто строку или многоязычную подпись с изображением.
Наши пользователи API должны иметь возможность отправить нам через JSON эти View
s одним из двух способов:
{"view": "just a string"}
или
{"view": {"caption": {...some caption structure...}}, "icon": {...some icon structure...}}
Мы можем добиться этого, используя специальный десериализатор:
@Override
public Display deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
TreeNode tree = jsonParser.getCodec().readTree(jsonParser);
if (tree.isValueNode()) {
return new View(((TextNode) tree).textValue());
} else {
MultilingualText caption = extractCaption(tree);
Icon icon = extractIcon(tree, "icon");
return new Display(caption, icon);
}
}
private MultilingualText extractCaption(TreeNode tree) {
TreeNode treeNode = tree.get("caption);
// error handling removed for simplicity
return mapper.treeToValue(treeNode, MultilingualText.class);
}
Обратите внимание, что в десериализаторе содержится ссылка на ObjectMapper
. Это позволяет нам отделить десериализаторы: ViewDeserializer
не нужно ничего знать о том, как или кто, например, десериализует MultilingualText
.
Но это означает, что мы должны передать ссылку на ObjectMapper
нашим десериализаторам с такой вложенной логикой (через конструктор). Это кажется странным, поскольку мы уже находимся в какой-то инфраструктуре синтаксического анализа, которая наверняка должна знать о текущей ObjectMapper
.
Вопросы:
- Есть ли способ получить ссылку на
ObjectMapper
внутри метода десериализатора (или, в равной степени, сериализатора) из его параметров?
- Есть ли лучший подход к этому, возможно, без использования ссылки
ObjectMapper
в целом? Ведь нам дан парсер и контекст.