想象一下,我有一个名为InfoItem
的抽象类,每个从其继承的类都是不同类型的信息类型,稍后将用于帮助我进行分类。
每个InfoItem
都有一个timestamp
作为属性(这个InfoItem
何时到达)?
注意:在此示例中,我使用的是 Lombok
@Data
@JsonTypeInfo(use = Id.NAME, visible = true, property = "@type")
public abstract class InfoItem {
private LocalDateTime timestamp;
}
我有2个扩展该类的类:Alpha
和Beta
。
每个类都有多个属性,它们之间没有共同的属性:
@JsonTypeName("alpha")
@Data
public class Alpha extends InfoItem {
private int x;
private long y;
}
@JsonTypeName("beta")
@Data
public class Beta extends InfoItem {
private bool isOk;
}
现在想象一下,我创建了一个InfoItem
个项目的列表:
list[0] = Alpha(x = 10, y = 20)
list[1] = Beta(isOk = false)
如果以上列表另存为名为lst
的变量,然后运行以下命令:
ObjectMapper mapper = new ObjectMapper();
String s = mapper.writeValueAsString(lst);
System.out.println(s);
我会得到这个:
[
{
"x": 10,
"y": 20
},
{
"isOk": false
}
]
代替:
[
{
"@type": "alpha",
"x": 10,
"y": 20
},
{
"@type": "beta",
"isOk": false
}
]
当我直接在ObjectMapper
上运行List
而不是我创建并在列表中放置的类时,就会发生这种情况。
如果我创建一个名为FooBar
的类,它具有一个属性lst
(类型为List,与上面相同):
@Data
public class FooBar {
private List<InfoItem> items;
}
然后我做
FooBar bar = new FooBar();
bar.setItems(lst);
ObjectMapper mapper = new ObjectMapper();
String s = mapper.writeValueAsString(lst);
System.out.println(s);
我会得到:
{
"items": [
{
"@type": "alpha",
"x": 10,
"y": 20
},
{
"@type": "beta",
"isOk": false
}
]
}
答案 0 :(得分:1)
如果您用以下内容注释abstract
类,则可以完成此操作(您可能需要根据需要对其进行调整):
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "_type")
@JsonSubTypes({
@JsonSubTypes.Type(value = Alpha.class, name = "_type"),
@JsonSubTypes.Type(value = Beta.class, name = "_type"),
})
生成JSON时,它将插入一个_type
,Alpha
等的FQDN类值的Beta
密钥。在您的用例中,它应该工作类似。 / p>
查看this是否有助于获得更多背景知识。不久前我在做类似的事情–我还没有更新问题:)
答案 1 :(得分:0)
几天后我找到了解决方法:
public static <T> Optional<String> toJson(final ObjectMapper mapper, final TypeReference<T> type, final T object) {
try {
return Optional.ofNullable(mapper.writer().forType(type).writeValueAsString(object));
} catch (JsonProcessingException e) {
return Optional.empty();
}
}
public static void main(String[] args) {
List<InfoItem> items = new ArrayList<>();
// Set values in items...
ObjectMapper mapper = new ObjectMapper();
Optional<String> json = toJson(mapper, new TypeReference<List<InfoItem>>() {}, items);
json.ifPresent(x -> System.out.println(x));
}