如何在 Jackson 中反序列化嵌套的包装字符串?
How can I deserialize a nested wrapped String in Jackson?
我有一个 JSON 字符串,其中包含嵌套和包装的 JSON 字符串。我想使用 Jackson 反序列化它,但我不确定如何。这是一个示例 bean:
@JsonIgnoreProperties(ignoreUnknown = true)
public class SomePerson {
public final String ssn;
public final String birthday;
public final Address address;
@JsonCreator
public SomePerson(
@JsonProperty("ssn") String ssn,
@JsonProperty("birthday") String birthday,
@JsonProperty("data") Address address,
@JsonProperty("related") List<String> related) {
this.ssn = ssn;
this.birthday = birthday;
this.address = address;
}
@JsonIgnoreProperties(ignoreUnknown = true)
public static class Address {
public final String city;
public final String country;
@JsonCreator
public Address(
@JsonProperty("city") String city,
@JsonProperty("country") String country) {
this.city = city;
this.country = country;
}
}
}
JSON 字符串类似于:
{
ssn: "001",
birthday: "01.01.2020",
address: "{ city: \"London\", country: \"UK\" }"
}
虽然我之前反序列化过 nsted 对象 - 当对象是一个包装字符串时,我不知道如何做到这一点。
readValue(String,Class)
应该有效:
Address addObject = mapper.readValue(root.getString("address"), Address.class);
其中 root
是您的主要 JSONObject
.
当内部对象被转义时JSON String
我们需要将它反序列化“两次”。第一次是 运行,当根 JSON Object
被反序列化时,第二次我们需要手动 运行。为此,我们需要实现实现 com.fasterxml.jackson.databind.deser.ContextualDeserializer
接口的自定义解串器。它可能看起来像这样:
class FromStringJsonDeserializer<T> extends StdDeserializer<T> implements ContextualDeserializer {
/**
* Required by library to instantiate base instance
* */
public FromStringJsonDeserializer() {
super(Object.class);
}
public FromStringJsonDeserializer(JavaType type) {
super(type);
}
@Override
public T deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
String value = p.getValueAsString();
return ((ObjectMapper) p.getCodec()).readValue(value, _valueType);
}
@Override
public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) {
return new FromStringJsonDeserializer<>(property.getType());
}
}
我们需要用这个 class 注释我们的 属性:
@JsonDeserialize(using = FromStringJsonDeserializer.class)
public final Address address;
从现在开始,您应该能够将以上 JSON
有效负载反序列化到您的 POJO
模型。
另请参阅:
- How to inject dependency into Jackson Custom deserializer
我有一个 JSON 字符串,其中包含嵌套和包装的 JSON 字符串。我想使用 Jackson 反序列化它,但我不确定如何。这是一个示例 bean:
@JsonIgnoreProperties(ignoreUnknown = true)
public class SomePerson {
public final String ssn;
public final String birthday;
public final Address address;
@JsonCreator
public SomePerson(
@JsonProperty("ssn") String ssn,
@JsonProperty("birthday") String birthday,
@JsonProperty("data") Address address,
@JsonProperty("related") List<String> related) {
this.ssn = ssn;
this.birthday = birthday;
this.address = address;
}
@JsonIgnoreProperties(ignoreUnknown = true)
public static class Address {
public final String city;
public final String country;
@JsonCreator
public Address(
@JsonProperty("city") String city,
@JsonProperty("country") String country) {
this.city = city;
this.country = country;
}
}
}
JSON 字符串类似于:
{
ssn: "001",
birthday: "01.01.2020",
address: "{ city: \"London\", country: \"UK\" }"
}
虽然我之前反序列化过 nsted 对象 - 当对象是一个包装字符串时,我不知道如何做到这一点。
readValue(String,Class)
应该有效:
Address addObject = mapper.readValue(root.getString("address"), Address.class);
其中 root
是您的主要 JSONObject
.
当内部对象被转义时JSON String
我们需要将它反序列化“两次”。第一次是 运行,当根 JSON Object
被反序列化时,第二次我们需要手动 运行。为此,我们需要实现实现 com.fasterxml.jackson.databind.deser.ContextualDeserializer
接口的自定义解串器。它可能看起来像这样:
class FromStringJsonDeserializer<T> extends StdDeserializer<T> implements ContextualDeserializer {
/**
* Required by library to instantiate base instance
* */
public FromStringJsonDeserializer() {
super(Object.class);
}
public FromStringJsonDeserializer(JavaType type) {
super(type);
}
@Override
public T deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
String value = p.getValueAsString();
return ((ObjectMapper) p.getCodec()).readValue(value, _valueType);
}
@Override
public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) {
return new FromStringJsonDeserializer<>(property.getType());
}
}
我们需要用这个 class 注释我们的 属性:
@JsonDeserialize(using = FromStringJsonDeserializer.class)
public final Address address;
从现在开始,您应该能够将以上 JSON
有效负载反序列化到您的 POJO
模型。
另请参阅:
- How to inject dependency into Jackson Custom deserializer