使用@JsonSubTypes反序列化没有值 - 缺少属性错误 [英] Deserialization with @JsonSubTypes for no value - missing property error

查看:383
本文介绍了使用@JsonSubTypes反序列化没有值 - 缺少属性错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将这样的jsons反序列化:

I deserialize jsons like this:

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

其中有效负载类型取决于类型。我的班级:

where payload type depends on 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;
    }

}

我还输入d没有有效载荷。如果我尝试反序列化:

I have also type "d" with no payload. If I try to deserialize:

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

它可以工作,但它不能用于无负载:

it works but it doesn't work with no payload:

{
  "type":"d",
}

如何让它与上一个例子一起使用?

How to make it work with last example?

我得到的Stacktrace错误:

Stacktrace of error that I get:

[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)


推荐答案

我也遇到过这个问题,并且找不到使用Jackson提供的机制的优雅解决方案(自定义 BeanDeserializer BeanDeserializerModifier 等。)。

I've also encountered this issue, and could not find an elegant solution using the mechanisms provided by Jackson (custom BeanDeserializer, BeanDeserializerModifier, etc.).

它看起来像处理外部类型ID的方式中的错误。我通过以下方式解决了这个问题:

It looks like a bug in the way external type IDs are handled. I worked around it by:


  1. 将JSON反序列化为 JsonNode ;

  2. 如果所需的属性不存在,则手动插入 null 节点;

  3. 映射 JsonNode 到我想要的值类型。

  1. deserializing the JSON tring to a JsonNode;
  2. manually inserting a null node if the required property is not present;
  3. mapping the JsonNode to my desired value type.

我的代码如下所示:

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

这篇关于使用@JsonSubTypes反序列化没有值 - 缺少属性错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆