简体   繁体   English

如何反序列化 Jackson 中的嵌套包装字符串?

[英]How can I deserialize a nested wrapped String in Jackson?

I have a JSON string that contains a nested and wrapped JSON string.我有一个 JSON 字符串,其中包含一个嵌套和包装的 JSON 字符串。 I'd like to deserialize this using Jackson but I'm unsure how.我想使用 Jackson 反序列化它,但我不确定如何。 Here's a sample bean:这是一个示例 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;
        }
    }
}

The JSON string resembles this: JSON 字符串如下所示:

{
  ssn: "001",
  birthday: "01.01.2020",
  address: "{ city: \"London\", country: \"UK\" }"
}

While I've deserialized nsted objects before - I'm rather lost as to how to do this when the object is a wrapped string.虽然我之前已经反序列化了 nsted 对象 - 当 object 是一个包装字符串时,我对如何执行此操作感到很迷茫。

When internal object is escaped JSON String we need to deserialise it "twice".当内部 object 转义JSON String时,我们需要将其反序列化“两次”。 First time is run when root JSON Object is deserialised and second time we need to run manually.第一次在 root JSON Object被反序列化时运行,第二次我们需要手动运行。 To do that we need to implement custom deserialiser which implements com.fasterxml.jackson.databind.deser.ContextualDeserializer interface.为此,我们需要实现自定义反序列化器,它实现com.fasterxml.jackson.databind.deser.ContextualDeserializer接口。 It could look like this:它可能看起来像这样:

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());
    }
}

We need to annotate our property with this class:我们需要用这个 class 来注释我们的属性:

@JsonDeserialize(using = FromStringJsonDeserializer.class)
public final Address address;

Since now, you should be able to deserialise above JSON payload to your POJO model.从现在开始,您应该能够将JSON有效负载反序列化到您的POJO model。

See also:也可以看看:

readValue(String,Class) should work: readValue(String,Class)应该工作:

Address addObject = mapper.readValue(root.getString("address"), Address.class);

Where root is your main JSONObject .其中root是您的主要JSONObject

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM