如何在 Jackson 自定义 JSON 反序列化器中使用常规 JSON 解释

How to use regular JSON interpretation inside of a Jackson custom JSON deserializer

我正在编写自定义解串器,但不确定如何最好地处理以下情况:

我正在反序列化如下所示的内容:

{
  "someProp": {
    "name": "some string"
    "value": ****** can be anything here, including string, number, object, etc. ******
  }
}

我将其映射到的对象有:

public class ObjectToMapTo {
    String name;
    Object value;
}

在我的代码中,我有 JsonNode 代表 someProp 字段。我显然可以提取 nameJsonNode 并使用 JsonNode.asText() 轻松将其转换为 String

可是,我该如何处理value呢? JsonNode 没有 asObject() 的方法。令人惊讶的是,它只有isObject()。我是否必须通过 switch 语句来弄清楚它是什么类型的东西,这样我才能调用正确的方法,如 asLong()asText()

但是即使我做了 switch 语句,如果 nodeTypeObject 怎么办?然后呢?如果我在没有自定义反序列化器的情况下使用 ObjectMapper,我如何才能使 JsonNode 成为常规 Java Map

恐怕你必须在这里做一些自定义反序列化和switching/iffing。

JsonNode does NOT have a method for asObject(). Surprisingly, it only has isObject().

是的。由于对象节点以 { 开头,因此确定该值是否为对象不是问题。但是具体能构造到什么class实例就没法猜了。这不足为奇。

what if the nodeType is Object. Then what? How do I get whatever is specified for value in JSON

如果有一个字段 - 比如说 type - 告诉你可以在自定义反序列化器中轻松完成的类型。因此,如果您有权添加它,那么您可以在其中提供整个 class 名称以在反序列化器中实例化。

否则我认为你能做的最好的事情就是将任意对象实例化为 Map 的实例或者只是作为 TreeNode.

您可以为反序列化器注释字段 value,例如(所以不是父项):

@Getter @Setter
public class ObjectToMapTo {
    private String name;
    @JsonDeserialize(using =  MyDeserializer.class)
    private Object value;
}

在你检查它不是数组也不是值之后,在你的反序列化器中,类似于:

Object o;
TreeNode valueTreeNode = jp.readValueAsTree();
// check if array or valueNode
// but if is object
ObjectMapper om = new ObjectMapper();
o = om.treeToValue(valueTreeNode, Map.class);
return o;