3

我对序列化没有太多经验。在尝试序列化下面类的简单对象时,我No JavaBean properties found exception从 YAML 库中得到了这个。

这是课程:

public class MyClass {
    String value;
    public MyClass(String args) {
        value = args;
    }

    public String getValue(){
        return value;
    }
}

以下是我使用 SnakeYAMAL 进行序列化的方式:

import java.util.HashMap;
import java.util.Map;

import org.yaml.snakeyaml.Yaml;


public class Test {

    public static void main(String[] args) {

        MyClass obj = new MyClass("this is my data");

        Map<String, Object> data = new HashMap<String, Object>();
        data.put("MyClass", obj);
        Yaml yaml = new Yaml();
        String output = yaml.dump(data);
        System.out.println(output);
    }

}

并在执行时引发此异常:

Exception in thread "main" org.yaml.snakeyaml.error.YAMLException: No JavaBean properties found in MyClass
    at org.yaml.snakeyaml.introspector.PropertyUtils.getProperties(PropertyUtils.java:112) ...

你能告诉我这样做我缺少什么,或者我应该如何正确地做到这一点?

编辑:

public class MyClass {
    String value;
    public MyClass() {}

    public String setValue(String value){
        this.value = value;
    }

    public String getValue(){
        return value;
    }
}

如果我在序列化它之前设置值,它会以某种方式工作。您认为这是正确的解决方案还是不推荐的方法?

4

1 回答 1

13

SnakeYAML 主要用于序列化 JavaBeans。

您上面给出的示例不符合 JavaBean 规范。要成为 JavaBean,对象必须有一个无参数的构造函数,并且每个字段都必须有一个 getter 和一个 setter。

如果你将你的类重写为一个 bean,SnakeYAML 应该可以毫无问题地序列化它。此外,SnakeYAML 可以序列化公共字段,因此如果您将value' 的可见性更改为publicSnakeYAML 将找到并序列化它。

如果你真的想避免改变MyClass,你可以明确告诉 SnakeYAML 序列化只读属性,如下所示:

PropertyUtils propUtils = new PropertyUtils();
propUtils.setAllowReadOnlyProperties(true);
Representer repr = new Representer();
repr.setPropertyUtils(propUtils);
Yaml yaml = new Yaml(new Constructor(), repr);

但是,将非 JavaBean 对象转储到 YAML 时可能会在您将它们反序列化回Object.

编辑:这是一个将 MyClass 转换为 JavaBean 的示例:

public class MyClass {
    String value;

    /* public, no-argument constructor */
    public MyClass() {
    }

    /* Every field has a public getter... */
    public String getValue(){
        return value;
    }

    /* ... and a public setter */
    public void setValue(String value) {
        this.value = value;
    }
}
于 2011-12-13T12:41:40.950 回答