如何解析“{}”空值(成字符串)

How to parse "{}" empty value (into String)

给定 json:

{
  "name" : {}
}

我想使用 com.fasterxml.jackson 将其解析为以下 Java 对象:

class MyClass {
  private String name;
}

如果你尝试一下,你会得到:

com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.lang.String` out of START_OBJECT token

有没有什么方法可以配置 jackson 反序列化器(全局最好)它可以将这些 empty objects 处理为 nulls 而无需更改属性类型(来自 String)?

为此,您可以编写自己的反序列化器。在 this 之后,您扩展 StdDeserializer 并将其注册到 class.


作者编辑:

我对字符串使用了以下反序列化器,它工作正常,谢谢:

public class EmptyObjectDeserializer extends StdDeserializer<String> {

    public EmptyObjectDeserializer() {
        this(null);
    }

    public EmptyObjectDeserializer(Class<?> vc) {
        super(vc);
    }

    @Override
    public String deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        JsonNode node = jp.getCodec().readTree(jp);
        return node.asText("");
    }
}

在 json 中,{} 是一个 Object,意味着它可以有字段(就像 Java 中的 POJO)。当您尝试将其反序列化为 String 时,它会抛出异常(想象一下试图将 POJO 分配给 Java 中的字符串引用)。

在这种情况下,有两种选择:

  • 将您的 class 配置为不包含空字段。这可以通过 ObjectMapper 实例上的注释或配置来完成,例如:

    @JsonInclude(Include.NON_NULL)
    class MyClass {
      private String name;
    }
    

    mapper.setSerializationInclusion(Include.NON_EMPTY);

    如果响应中的 name 不为空,则此选项可能不起作用。如果它是一个不具有空值的对象,Jackson 将尝试将其反序列化为 String 并失败。

  • name 的类型更改为 Object(或者更确切地说,一个包含响应可以包含的所有元素的 POJO)。然而,这意味着您需要更改访问 name 元素的代码,因为它将不再是 String.

无需编写自己的反序列化器,只需将名称对象封装在 class 中即可:

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
        "name"
})
public class JsonExample {
        @JsonProperty("name")
        public Name name;
}

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
        "first",
        "last"
})
public class Name {
    @JsonProperty("first")
    public String first_name;
    @JsonProperty("last")
    public String last_name;
}

此处以名字和姓氏为例...不知道您的 Name 对象中包含什么 所以你可以使用你的映射器:

JsonExample obj = mapper.readValue(file, JsonExample.class);