给出以下yml:
---
commands:
dev: !foo.bar.Baz {}
以下课程
public class PluginFile {
private Map<String, Command> commands = new HashMap<String, Command>();
public Map<String, Command> getCommands() {
return commands;
}
public void setCommands(Map<String, Command> commands) {
this.commands = commands;
}
阅读文件:
mapper.readValue(theFile, PluginFile.class);
导致错误:
com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of foo.bar.command.Command, problem: abstract types either need to be mapped to concrete types, have custom deserializer, or be instantiated with additional type information
at [Source: C:\theFile.yml; line: 3, column: 10] (through reference chain: foo.bar.PluginFile["commands"]->java.util.LinkedHashMap["dev"])
这似乎是说杰克逊无法确定要在pluginFile.commands()上设置的Command的具体实例。但是,该类型是由yml文件本身使用!foo.bar.DevCommand {}语法定义和创建的。
我可以使用以下yaml来实现这一点:
---
commands:
dev:
type: foo.bar.Baz
然后注释地图属性:
@JsonTypeInfo(use=JsonTypeInfo.Id.CLASS, include=JsonTypeInfo.As.PROPERTY, property="type")
但我真的想使用yaml Java文字语法。
答案 0 :(得分:1)
基类Command
需要@JsonTypeInfo
来表明它需要多态处理;如果是这样,杰克逊会知道要查找YAML内容所具有的类型标识符。如果foo.bar.Baz
指定了一个类(即包foo.bar
,类Baz
),则类型包含应指定为&#34;类名&#34;。
或者,您也可以为地图属性指定@JsonTypeInfo
。类似的东西:
public class PluginFile {
@JsonTypeInfo(use=JsonTypeInfo.Id.CLASS)
private Map<String, Command> commands = new HashMap<String, Command>();
}