当前位置: 首页 > 知识库问答 >
问题:

使用@JsonSubtypes反序列化无值-缺少属性错误

卫阳曜
2023-03-14

我像这样反序列化jsons:

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

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

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

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

我得到的错误的堆栈跟踪:

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

共有1个答案

丌官利
2023-03-14

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

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

  1. 将JSON试验反序列化为JSONNODe
  2. 如果所需属性不存在,则手动插入节点;
  3. JsonNode映射到所需的值类型。

我的代码如下所示:

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);
}
 类似资料:
  • 问题内容: 我像这样反序列化json: 有效负载类型取决于类型。我的课: 我也输入了没有有效载荷的“ d”。如果我尝试反序列化: 它可以工作,但不能在没有有效负载的情况下工作: 如何使其与上一个示例一起使用? 我得到的错误的Stacktrace: 问题答案: 我也遇到了这个问题,找不到利用杰克逊(定制提供的机制的一流解决方案,等等)。 看起来像是处理外部类型ID的方式中的错误。我通过以下方法解决了

  • 我的JSON字符串是: 我想要实现的是,当JSON中没有提供schemaVersion时,能够在默认情况下反序列化到SubClassV1,但即使在Superclass中将schemaVersion初始化为“1.0”时,我仍然会收到以下错误:

  • 问题内容: 使用Jackson 2,我正在寻找一种 通用的 方式将对象序列化为单个值(然后序列化它们,然后再填充该单个字段),而不必重复创建JsonSerializer / JsonDeserializer来处理每种情况。@JsonIdentityInfo批注非常接近,但由于我知道,它将始终对完整的子对象进行序列化,因此略微遗漏了该标记。 这是我想做的一个例子。给定的类: 我希望Order可以序列

  • 我有一个类,它用Data合同和Data会员属性进行了注释。一些成员被标记为。当我通过Json的线路序列化实例时。NET,并且所需的对象成员具有空值,然后它们的序列化值在输出中丢失(这显然相当于在JSON中为空)。我没意见。 我创建了一种“echo”服务,它返回作为响应发送给它的数据。因此,此服务接收缺少成员的JSON(或空成员,具体取决于您如何看待它),然后将其发送回我的JSON。NET客户端。通

  • 我正在尝试为接受JSON输入的前端库创建一个java SDK。本质上,此SDK将特定类型的对象转换为JSON,然后由前端库使用。 我正在使用杰克逊的多态序列化/反序列化使用它的注释系统。 我有一个基类a和扩展a的两个子类B和C。类a有一个类型字段,我用它来决定要使用哪个类(B或C)。语法如下所示: 现在,当我使用Jackson的ObjectMapper函数读取字符串化的JSON并转换为类A时,我根