如何解析“{}”空值(成字符串)
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);
给定 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);