SnakeYAML:如何设置要加载的 bean 属性 类型
SnakeYAML: How to set bean property type for loading
使用 SnakeYAML 的 TypeDescription
,我可以使用以下方法添加有关列表和地图的类型信息:
TypeDescription td = new TypeDescription(MyBean.class, "!mybean");
td.putMapPropertyType("mymap", String.class, MyOtherBean.class);
td.putListPropertyType("mylist", MyOtherBean.class);
这样,我可以使用 MyOtherBean 实例填充集合,而无需依赖任何其他标签:
---
!mybean
mymap:
foobar: # will map to an instance of MyOtherBean
otherbeanprop1: foo
otherbeanprop2: bar
mylist: # will contain instances of MyOtherBean
- otherbeanprop1: foo
otherbeanprop2: bar
有没有简单的方法可以做这样的事情:
td.putPropertyType("myotherbean", MyOtherBean.class);
以便 MyBean
中的 属性 myotherbean
将填充 MyOtherBean
的单个实例?我试图避免的事情:
- 在 yaml 文件中添加额外的标签(如
!myotherbean
)
- 从 Map 加载其他 bean 属性并自己构建 bean
我已经试过了,我想我需要创建一个像这样的自定义构造函数(改编自 SnakeYAML 文档):
class SelectiveConstructor extends Constructor {
public SelectiveConstructor() {
// define a custom way to create a mapping node
yamlClassConstructors.put(NodeId.mapping, new ConstructMapping() {
@Override
protected Object constructJavaBean2ndStep(MappingNode node, Object object) {
Class type = node.getType();
if (type.equals(MyBean.class)) {
// something
if (propertyname.equals("myotherbean")) {
// something
}
} else {
// redirect creation to Constructor
return super.constructJavaBean2ndStep(node, object);
}
}
}
}
问题是我真的不明白那里到底发生了什么。
如果有更简单的方法,请告诉我。如果没有,请分享您的经验,我将不胜感激。
有一种优雅的方法可以做到这一点。
如果你不想对 YAML 内容做一些特殊的技巧,你可以使用 snakeYaml 的以下两种方法来转储和加载 yaml 内容:
public String dumpAsMap(Object data) // dump method
public <T> T loadAs(Reader io, Class<T> type) // load method
在您的场景中,
转储:
MyBean bean = new MyBean();
// init bean...
String yamlContent = yaml.dumpAsMap(bean);
加载:
FileReader reader = new FileReader(filename);
MyBean bean = yaml.loadAs(reader, MyBean.class);
当然,您应该实现 类 的 getter 和 setter。详情可以看这里example
使用 SnakeYAML 的 TypeDescription
,我可以使用以下方法添加有关列表和地图的类型信息:
TypeDescription td = new TypeDescription(MyBean.class, "!mybean");
td.putMapPropertyType("mymap", String.class, MyOtherBean.class);
td.putListPropertyType("mylist", MyOtherBean.class);
这样,我可以使用 MyOtherBean 实例填充集合,而无需依赖任何其他标签:
---
!mybean
mymap:
foobar: # will map to an instance of MyOtherBean
otherbeanprop1: foo
otherbeanprop2: bar
mylist: # will contain instances of MyOtherBean
- otherbeanprop1: foo
otherbeanprop2: bar
有没有简单的方法可以做这样的事情:
td.putPropertyType("myotherbean", MyOtherBean.class);
以便 MyBean
中的 属性 myotherbean
将填充 MyOtherBean
的单个实例?我试图避免的事情:
- 在 yaml 文件中添加额外的标签(如
!myotherbean
) - 从 Map 加载其他 bean 属性并自己构建 bean
我已经试过了,我想我需要创建一个像这样的自定义构造函数(改编自 SnakeYAML 文档):
class SelectiveConstructor extends Constructor {
public SelectiveConstructor() {
// define a custom way to create a mapping node
yamlClassConstructors.put(NodeId.mapping, new ConstructMapping() {
@Override
protected Object constructJavaBean2ndStep(MappingNode node, Object object) {
Class type = node.getType();
if (type.equals(MyBean.class)) {
// something
if (propertyname.equals("myotherbean")) {
// something
}
} else {
// redirect creation to Constructor
return super.constructJavaBean2ndStep(node, object);
}
}
}
}
问题是我真的不明白那里到底发生了什么。 如果有更简单的方法,请告诉我。如果没有,请分享您的经验,我将不胜感激。
有一种优雅的方法可以做到这一点。
如果你不想对 YAML 内容做一些特殊的技巧,你可以使用 snakeYaml 的以下两种方法来转储和加载 yaml 内容:
public String dumpAsMap(Object data) // dump method
public <T> T loadAs(Reader io, Class<T> type) // load method
在您的场景中,
转储:
MyBean bean = new MyBean();
// init bean...
String yamlContent = yaml.dumpAsMap(bean);
加载:
FileReader reader = new FileReader(filename);
MyBean bean = yaml.loadAs(reader, MyBean.class);
当然,您应该实现 类 的 getter 和 setter。详情可以看这里example