使用 ID.DEDUCTION 的 Jackson 多态性

问题描述 投票:0回答:1

我有一个类层次结构,我尝试对其进行序列化和反序列化。我知道最简单的方法是使用

Id.DEDUCTION
- 我试图让它在下面的代码上工作,但我遇到了异常,你知道吗?

@JsonTypeInfo(use = Id.DEDUCTION)
@JsonSubTypes({ //
    @Type(CustomTask.class), //
    @Type(ExtendedTask.class) //
})
class abstract Task {

  private final long id;
  private final long threshold;
  private final List<Integer> params;

  public Task(long id, long threshold, List<Integer> params) {
    this.id = id;
    this.threshold = threshold;
    this.params = params;
  }
}

public class CustomTask extends Task {

  @JsonCreator
  public CustomTask(
    @JsonProperty("id") long id, 
    @JsonProperty("tHd") long threshold, 
    @JsonProperty("prms") List<Integer> params) {

    super(id, threshold, params);  
  }
}

public class ExtendedTask extends Task {

  private final int count;

  private final List<Long> inventory;

  @JsonCreator
  public ExtendedTask(
    @JsonProperty("id") long id, 
    @JsonProperty("tHd") long threshold, 
    @JsonProperty("prms") List<Integer> params,
    @JsonProperty("cnt") int count,
    @JsonProperty("inv") List<Long> inventory) {

    super(id, threshold, params);  
    this.count = count;
    this.inventory = inventory;
  }
}

当我尝试反序列化以下 JSON 字符串时:

{"id":9,"tHd":0,"prms":[200, 204, 208]}

它抛出一个

InvalidTypeIdException
异常,告诉我有 2 个候选者匹配。

如果我反序列化以下 JSON 字符串:

{"id":9,"tHd":0,"prms":[200, 204, 208],"cnt":1000,"inv":[1000,1001,1002]}

然后它运行良好并按预期创建了

ExtendedTask
的实例。

问题是,由于两个派生类共享一些相同的属性,因此它无法确定要实例化哪个类 - 有更好的方法来解决这个问题吗?

谢谢!

java jackson json-deserialization
1个回答
0
投票

您的 JSON

{"id":9,"tHd":0,"prms":[200, 204, 208]}
太模糊了,因为它与您的两个类的指纹(
CustomTask
ExtendedTask
)匹配,正如您在问题中已经说过的:

问题是,由于两个派生类共享一些相同的属性,因此它无法确定要实例化哪个类

这种情况已经在 GitHub 上 Jackson 官方存储库的问题 3357 中得到解决。在这种情况下,由于 Jackson 无法为给定的 JSON 选择唯一的候选者,因此您需要依靠问题线程中建议的不同逻辑,例如

JsonTypeInfo.As.PROPERTY
JsonTypeInfo.As.EXTERNAL_PROPERTY

这里是类似问题的链接,其中我提供了一个 answer,其中包含

JsonTypeInfo.As.PROPERTY
JsonTypeInfo.As.EXTERNAL_PROPERTY
的实现,作为
JsonTypeInfo.Id.DEDUCTION
的替代品。

© www.soinside.com 2019 - 2024. All rights reserved.