如何在Jackson的自定义反序列化器中访问ObjectMapper?

时间:2019-06-07 12:24:38

标签: json jackson jackson-databind

我们有一个View类,它是一个变体:它可能只包含一个简单的字符串或带有图像的多语言标题。

我们的API用户应该可以使用以下两种方式之一通过JSON将这些View发送给我们:

{"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引用?毕竟,我们有一个解析器和上下文。

1 个答案:

答案 0 :(得分:0)

尝试检查当前令牌,并根据其类型(文本节点或对象节点)使用不同的嵌入式反序列化器反序列化。 在解串器中注入ObjectMaper是错误的,因为通常您会将解串器注入到mapper中。

这是一些教程: http://tutorials.jenkov.com/java-json/jackson-objectmapper.html#custom-deserializer

相关问题