Java – deserialization with @ jsonsubtypes without value – missing attribute error

I deserialize jsons like this:

{
  "type":"a","payload" : {...}
}

The type of payload depends on the type My class:

public class Sth<T extends Payload> {

    @JsonProperty("type")
    private String type;
    @Valid
    private T payload;

    @JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,include = JsonTypeInfo.As.EXTERNAL_PROPERTY,property = "type",visible = true,defaultImpl = NoClass.class)
    @JsonSubTypes({
        @JsonSubTypes.Type(value = APayload.class,name = "a"),@JsonSubTypes.Type(value = BPayload.class,name = "b"),@JsonSubTypes.Type(value = CPayload.class,name = "c")})
    public void setPayload(T payload) {
    this.payload = payload;
    }

    public void setType(String type) {
    this.type = type;
    }

}

I also entered "d" without payload If I try to deserialize:

{
  "type":"d","payload" : null
}

It works, but it has no payload:

{
  "type":"d",}

How do I make it work with the previous example?

I got the wrong stacktrace:

[error] Caused by: com.fasterxml.jackson.databind.JsonMappingException: Missing property 'payload' for external type id 'type
[error]  at [Source: N/A; line: -1,column: -1]
[error]     at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:164)
[error]     at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:700)
[error]     at com.fasterxml.jackson.databind.deser.impl.ExternalTypeHandler.complete(ExternalTypeHandler.java:160)
[error]     at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeWithExternalTypeId(BeanDeserializer.java:690)
[error]     at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeWithExternalTypeId(BeanDeserializer.java:639)
[error]     at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:266)
[error]     at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:124)
[error]     at com.fasterxml.jackson.databind.ObjectMapper._readValue(ObjectMapper.java:2965)
[error]     at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:1587)
[error]     at com.fasterxml.jackson.databind.ObjectMapper.treeToValue(ObjectMapper.java:1931)
[error]     at play.libs.Json.fromJson(Json.java:47)

Solution

I have also encountered this problem, and I can't find an elegant solution using the mechanisms provided by Jackson (custom beandeserializer, beandeserializer modifier, etc.)

It looks like an error in the way the external type ID is handled I solved the following problems:

>Deserialize JSON string to jsonnode; > If the required attribute does not exist, insert the empty node manually; > Map jsonnode to the value type I want

My code is as follows:

public <T> T decode(String json,Class<T> type) throws IOException {
    JsonNode jsonNode = mapper.readTree(json);

    if (jsonNode.isObject() && (jsonNode.get("payload") == null  || jsonNode.get("payload").size() == 0)) {
        ObjectNode objectNode = (ObjectNode) jsonNode;
        objectNode.putNull("payload");
    }

    return mapper.treeToValue(jsonNode,type);
}
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>