Java XML序列化仅序列化一个字段
XMLEncoder有以下问题。我想序列化一个如下所示的类:Java XML序列化仅序列化一个字段,java,xml,serialization,Java,Xml,Serialization,XMLEncoder有以下问题。我想序列化一个如下所示的类: public class MyClass{ private Object myObject; private Object anotherObject; private static MyClass instance = new MyClass(); [myObject and anotherObject are set in the class later...] public stati
public class MyClass{
private Object myObject;
private Object anotherObject;
private static MyClass instance = new MyClass();
[myObject and anotherObject are set in the class later...]
public static MyClass getInstance(){
return instance;
}
[getter and setter methods here]
}
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.6.0_24" class="java.beans.XMLDecoder">
<object class="MyClass"/>
</java>
现在我想像这样序列化对象(在MyClass中):
但是my object.xml不包含myObject和anotherInstance的值,如下所示:
public class MyClass{
private Object myObject;
private Object anotherObject;
private static MyClass instance = new MyClass();
[myObject and anotherObject are set in the class later...]
public static MyClass getInstance(){
return instance;
}
[getter and setter methods here]
}
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.6.0_24" class="java.beans.XMLDecoder">
<object class="MyClass"/>
</java>
那里发生了什么事?XMLEncoder是否检测到具有相同类的静态字段的循环,并且不进一步序列化它?但是我没有得到任何错误。。。
我可以将该字段标记为不可序列化或其他内容吗?编码“Java bean”。它不了解这些领域;它只使用getter和setter。如果有一个“循环”,那么它将使用
xml:id
和xml:idref
来处理引用。编码“Java bean”。它不了解这些领域;它只使用getter和setter。如果存在“循环”,那么它将使用xml:id
和xml:idref
来处理引用。XMLEncoder设计用于JavaBeans。这意味着序列化树中的所有对象必须:
- 具有公共默认(即无参数)构造函数
- 要序列化的每个属性都有一个getter和一个setter(用于序列化的getter和用于反序列化的setter)
// let's get the BeanInfo of class MyClass
BeanInfo info = Introspector.getBeanInfo(MyClass.class);
// we'll work with PropertyDescriptors to prevent the bar attribute from being serialized
PropertyDescriptor[] propertyDescriptors = info.getPropertyDescriptors();
for (PropertyDescriptor descriptor : propertyDescriptors) {
if (descriptor.getName().equals("bar")) {
//the correct PropertyDescriptor is set to transient.
//Note that you actually have to do this via the BeanInfo/PropertyDescriptor for it to work
descriptor.setValue("transient", Boolean.TRUE);
}
}
XMLEncoder设计用于JavaBeans。这意味着序列化树中的所有对象必须:
- 具有公共默认(即无参数)构造函数
- 要序列化的每个属性都有一个getter和一个setter(用于序列化的getter和用于反序列化的setter)
// let's get the BeanInfo of class MyClass
BeanInfo info = Introspector.getBeanInfo(MyClass.class);
// we'll work with PropertyDescriptors to prevent the bar attribute from being serialized
PropertyDescriptor[] propertyDescriptors = info.getPropertyDescriptors();
for (PropertyDescriptor descriptor : propertyDescriptors) {
if (descriptor.getName().equals("bar")) {
//the correct PropertyDescriptor is set to transient.
//Note that you actually have to do this via the BeanInfo/PropertyDescriptor for it to work
descriptor.setValue("transient", Boolean.TRUE);
}
}
如果您想在任何类(不遵守JavaBeans约定的类)上使用XmlEncoder,这里有一个有用的链接 编辑:这里有一个小广告,可能对你有帮助 XMLEncoder通过克隆对象图并记录创建克隆所需的步骤来工作。通过这种方式,XMLEncoder有一个对象图的“工作副本”,它模仿XMLDecoder解码文件所需的步骤。通过监视此工作副本的状态,编码器可以省略将属性值设置为默认值的操作,从而生成具有极少冗余信息的简明文档。 因此,在您的示例中,如果在
实例
变量上设置了myObject
和另一个对象
的值,而不是将其初始化为默认值,则一切正常
public void saveObject(){
[try catch stuff not shown]
instance.setObject(new Object());
FileOutputStream fos = new FileOutputStream(new File("object.xml"));
XMLEncoder xmle = new XMLEncoder(fos);
xmle.writeObject(instance);
xmle.close();
}
如果您想在任何类(不遵守JavaBeans约定的类)上使用XmlEncoder,这里有一个有用的链接 编辑:这里有一个小广告,可能对你有帮助 XMLEncoder通过克隆对象图并记录创建克隆所需的步骤来工作。通过这种方式,XMLEncoder有一个对象图的“工作副本”,它模仿XMLDecoder解码文件所需的步骤。通过监视此工作副本的状态,编码器可以省略将属性值设置为默认值的操作,从而生成具有极少冗余信息的简明文档。 因此,在您的示例中,如果在
实例
变量上设置了myObject
和另一个对象
的值,而不是将其初始化为默认值,则一切正常
public void saveObject(){
[try catch stuff not shown]
instance.setObject(new Object());
FileOutputStream fos = new FileOutputStream(new File("object.xml"));
XMLEncoder xmle = new XMLEncoder(fos);
xmle.writeObject(instance);
xmle.close();
}
嗯,这不是我第一次使用XMLEncoder,它总是像你描述的那样工作。。。但在这种情况下,它不工作!即使我把所有init的东西都放在构造函数中…嗯,这不是我第一次使用XMLEncoder,它总是像你描述的那样工作。。。但在这种情况下,它不工作!即使我把所有的init元素都放在一个构造函数中…是的,我有我的getter和setter,但是这些方法不知怎么没有被使用?@reox所以你要求我们调试你没有包含在OP中的代码,而不是你做的代码?是的,我有我的getter和setter,但是这些方法不知怎么没有被使用?@reox所以你要求我们调试你没有包含在OP中的代码,而不是你做的代码?同意。一个特别常见的问题是,当试图编码一个对象A时,该对象A包含一个没有公共默认(无参数)构造函数的对象B作为成员。在这种情况下,B将不会出现在编码版本中。同意。一个特别常见的问题是,当试图编码一个对象A时,该对象A包含一个没有公共默认(无参数)构造函数的对象B作为成员。在这种情况下,B将不会出现在编码版本中。