我有一个类层次结构,我尝试对其进行序列化和反序列化。我知道最简单的方法是使用
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
的实例。
问题是,由于两个派生类共享一些相同的属性,因此它无法确定要实例化哪个类 - 有更好的方法来解决这个问题吗?
谢谢!
您的 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
的替代品。