SnakeYAML:如何设置bean属性类型以进行加载

时间:2016-04-22 08:53:19

标签: java yaml javabeans snakeyaml

使用SnakeYAML TypeDescription,我可以使用以下方式添加有关列表和地图的类型信息:

TypeDescription td = new TypeDescription(MyBean.class, "!mybean");
td.putMapPropertyType("mymap", String.class, MyOtherBean.class);
td.putListPropertyType("mylist", MyOtherBean.class);

这样,我可以使用MyOtherBean实例填充Collections,而不必依赖任何其他标记:

---
!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);

这样myotherbean中的MyBean属性是否会填充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);
                }

        }
    }
}

问题在于我并不真正理解那里到底发生了什么。 如果有更简单的方法,请告诉我。如果没有,如果您与我分享您的经验,我将不胜感激。

1 个答案:

答案 0 :(得分:2)

有一种优雅的方法可以做到这一点。
如果您不想使用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