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

Mri*_*lla 6 java jackson mongo-jackson-mapper jackson2

我有一个 JSON 字符串,其中包含嵌套和包装的 JSON 字符串。我想使用杰克逊反序列化它,但我不确定如何。这是一个示例 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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

JSON 字符串类似于:

{
  ssn: "001",
  birthday: "01.01.2020",
  address: "{ city: \"London\", country: \"UK\" }"
}
Run Code Online (Sandbox Code Playgroud)

虽然我之前已经反序列化过 nsted 对象,但当对象是包装字符串时,我很不知道如何执行此操作。

Mic*_*ber 8

当内部对象被转义时,JSON String我们需要将其反序列化“两次”。第一次是在 rootJSON 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());
    }
}
Run Code Online (Sandbox Code Playgroud)

我们需要用这个类来注释我们的属性:

@JsonDeserialize(using = FromStringJsonDeserializer.class)
public final Address address;
Run Code Online (Sandbox Code Playgroud)

从现在开始,您应该能够将上述JSON有效负载反序列化到您的POJO模型中。

也可以看看: