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

Java 如何在Jackson中反序列化嵌套的包装字符串?,java,jackson,jackson2,mongo-jackson-mapper,Java,Jackson,Jackson2,Mongo Jackson Mapper,我有一个JSON字符串,它包含一个嵌套和包装的JSON字符串。我想用Jackson反序列化这个,但我不确定怎么做。下面是一个示例bean: @JsonIgnoreProperties(ignoreUnknown = true) public class SomePerson { public final String ssn; public final String birthday; public final Address address; @JsonCr

我有一个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;
        }
    }
}
虽然我以前反序列化过nsted对象,但当对象是包装字符串时,我不知道如何进行反序列化。

应该可以:

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

其中
root
是您的主
JSONObject

当内部对象被转义
JSON字符串时,我们需要“两次”反序列化它。第一次是在root
JSON对象
被反序列化时运行,第二次需要手动运行。为此,我们需要实现自定义反序列化程序,该程序实现
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());
    }
}
从现在起,您应该能够将上面的
JSON
负载反序列化到您的
POJO
模型

另见:


为什么“地址”在您的模型中是一个字符串?它应该是地址类型的一个实例。对不起,我的错。那是个打字错误。你看到我的答案了吗?另请看:
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());
    }
}
@JsonDeserialize(using = FromStringJsonDeserializer.class)
public final Address address;