XML序列化仅序列化一个字段

时间:2011-12-23 14:10:46

标签: 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 static MyClass getInstance(){
        return instance;
    }

    [getter and setter methods here] 
}

现在我想像这样序列化对象(在MyClass中):

 public void saveObject(){
        [try catch stuff not shown]
        FileOutputStream fos = new FileOutputStream(new File("object.xml"));
    XMLEncoder xmle = new XMLEncoder(fos);
    xmle.writeObject(instance);
    xmle.close();
}

但我的object.xml不包含myObject和anotherInstance的值,如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<java version="1.6.0_24" class="java.beans.XMLDecoder">
 <object class="MyClass"/>
</java>
那是怎么回事? XMLEncoder是否检测到具有相同类的静态Field的循环,并且不进一步序列化它?但我没有得到任何错误...... 我可以将该字段标记为“不可序列化”或其他内容吗?

3 个答案:

答案 0 :(得分:2)

XMLEncoder编码'Java Beans'。它没有意识到这些领域;它只使用getter和setter。如果存在“循环”,那么它将使用xml:idxml:idref来处理引用。

答案 1 :(得分:1)

XMLEncoder旨在用于JavaBeans。它意味着序列化树中的所有对象必须:

  • 有一个公共默认(即无参数)构造函数

  • 为要序列化的每个属性都有一个getter和一个setter(一个用于序列化的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);
   }
}

答案 2 :(得分:1)

如果你想在任何类(不遵守JavaBeans约定的类)上使用XmlEncoder,这是一个有用的链接。

Advanced use of XmlEncoder

编辑:那里有一点点可能对你有所帮助。

XMLEncoder通过克隆对象图并记录创建克隆所需的步骤来工作。这样,XMLEncoder具有对象图的“工作副本”,模仿XMLDecoder解码文件所需的步骤。通过监视此工作副本的状态,编码器能够省略将属性值设置为其默认值的操作,从而生成具有非常少的冗余信息的简明文档。

因此,在您的示例中,如果myObjectanotherObject的值设置在instance变量上而不是默认初始化,则一切都按预期工作。

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();
}