Как получить доступ к ObjectMapper в пользовательском десериализаторе в Джексоне? - PullRequest
0 голосов
/ 07 июня 2019

У нас есть класс 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.

Вопросы:

  1. Есть ли способ получить ссылку на ObjectMapper внутри метода десериализатора (или, в равной степени, сериализатора) из его параметров?
  2. Есть ли лучший подход к этому, возможно, без использования ссылки ObjectMapper в целом? Ведь нам дан парсер и контекст.
...