提问人:Marco 提问时间:11/7/2023 更新时间:11/7/2023 访问量:21
如何反序列化其他抽象的抽象子类型?
How to deserialize an abstract subtype of an other abstract?
问:
没有为此目的在网络上找到任何东西。 我有一个通用的抽象类
@Data
@AllArgsConstructor
@NoArgsConstructor
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.EXISTING_PROPERTY,
property = "elementType",
visible = true
)
@JsonSubTypes({
@JsonSubTypes.Type(name = "ENUM1", value = Abstract1.class),
@JsonSubTypes.Type(name = "ENUM2", value = Abstract2.class)
})
public abstract class Element {
protected String id;
protected ElementType elementType;
}
其中 ElementType 为
public enum ElementType {
ENUM1, ENUM2
}
然后我有 2 个抽象类。我只发布一个,另一个是相同的,除了传递的 property1 值:
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.EXISTING_PROPERTY,
property = "property1",
visible = true
)
@JsonSubTypes({
@JsonSubTypes.Type(name = "value1", value = Concrete1.class),
@JsonSubTypes.Type(name = "value2", value = Concrete2.class)
})
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
public abstract class Abstract1 extends Element {
protected String property1;
protected Abstract1(...) {
super(id, ElementType.ENUM1);
...
}
}
Concrete1 是:
@EqualsAndHashCode(callSuper = true)
@Data
@NoArgsConstructor
public class Concrete1 extends Abstract1 {
public Concrete1(...) {
super(id, "property string");
}
}
因此,我尝试反序列化json:
{
"id": "an id",
"elementType": "ENUM1",
"property1": "value1"
}
@Test
public void concrete1Test() throws IOException {
String json = "...";
Element element = mapper.readValue(json, Element.class);
Assert.assertTrue(element instanceof Concrete1); <---- fail
}
断言失败,因为最后一个元素以 Concrete2 的形式出现。这就像它正在选择第一个可用于反序列化的具体类。 我已经调查并发现,也许我应该为 Concrete1 和 2 的特定反序列化注册模块。他们必须井井有条。我注册了它们
@Test
public void concrete1Test() throws IOException {
...
mapper.registerModule(new SimpleModule("Concrete1Module", Version.unknownVersion())
.addDeserializer(Concrete1.class, new Concrete1Deserializer())
.addDeserializer(Concrete2.class, new Concrete2Deserializer()));
Element element = mapper.readValue(json, Element.class);
Assert.assertTrue(element instanceof Concrete1);
}
但它仍然在回馈 Concrete2。
事实是,我正在尝试将一个元素反序列化,我将在我的控制器中将其作为正文请求,到一个 Concrete1 类,知道
Concrete1 extends (Abstract1 extends Element)
所以必须从 Element 返回到 Concrete1,通过 Abstract1。这是一件可行的事情吗?我错过了什么吗?
答: 暂无答案
评论
JsonSubTypes
Element