我对序列化没有多少经验。在尝试序列化下面类的一个简单对象时,我从YAML库中获取此No JavaBean properties found exception
。
这是班级:
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;
}
}
如果我在序列化之前设置了值,它会以某种方式工作。 您认为这是正确的解决方案还是不推荐的方法?
答案 0 :(得分:10)
SnakeYAML主要用于序列化JavaBeans。
上面给出的示例不符合JavaBean规范。要成为JavaBean,对象必须具有无参数构造函数,并且每个字段都必须具有getter和setter。
如果您将类重写为bean,SnakeYAML应该没有问题地序列化它。此外,SnakeYAML可以序列化公共字段,因此如果您将value
的可见性更改为public
,则SnakeYAML会查找并序列化它。
如果你真的想避免改变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
时导致问题,所以我建议使用JavaBeans作为最简单和最安全的解决方案。
编辑:以下是转换为JavaBean的MyClass示例:
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;
}
}