给定的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
有没有办法配置杰克逊反序列化程序(全局为最佳),它可以nulls
处理这些empty objects
而无需更改属性类型(从字符串)?
您可以编写自己的反序列化程序。在此之后,扩展 StdDeserializer 并将其注册到类中。
作者编辑:
我已经对字符串使用了以下反序列化器,它工作正常,谢谢:
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中的字符串引用)。
在这种情况下,有两个选项:
-
将类配置为不包含空字段。这可以通过
ObjectMapper
实例上的注释或配置来完成,例如:@JsonInclude(Include.NON_NULL) class MyClass { private String name; }
或
mapper.setSerializationInclusion(Include.NON_EMPTY);
如果响应中没有空
name
,则此选项可能不起作用。如果它是一个非 null 值的对象,Jackson 将尝试将其反序列化为String
并失败。 -
将
name
类型更改为Object
(或者更确切地说,具有响应可以包含的所有元素的 POJO)。但是,这意味着您需要更改访问name
元素的代码,因为它将不再String
。
无需编写自己的反序列化器,您只需要将名称对象封装在类中即可:
@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);