Reputation: 5217
I have the following Problem with the XMLEncoder. I want to Serialize a Class that looks like this:
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]
}
Now i want to Serialize the Object like this (inside 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();
}
But my object.xml does not contain the Values of myObject and anotherInstance and looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.6.0_24" class="java.beans.XMLDecoder">
<object class="MyClass"/>
</java>
Whats going on there? Does the XMLEncoder detect a loop with the static Field of the Same Class and does not serialize it further? But i dont get any error... Can i Mark that field as Not Serializable or something else?
Upvotes: 1
Views: 1470
Reputation: 24910
If you want to use XmlEncoder on any class ( classes that dont adhere to JavaBeans conventions ) , here is a helpful link.
EDIT: There is a little blurb in there that might be of help to you.
XMLEncoder works by cloning the object graph and recording the steps that were necessary to create the clone. This way XMLEncoder has a "working copy" of the object graph that mimics the steps XMLDecoder would take to decode the file. By monitoring the state of this working copy, the encoder is able to omit operations that would set property values to their default value, producing concise documents with very little redundant information.
So, in your example, if the values of myObject
and anotherObject
are set on the instance
variable instead of being initialized as default, everything works as expected.
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();
}
Upvotes: 1
Reputation: 28301
XMLEncoder is designed to work on JavaBeans. It implies that all your objects in the serialization tree must:
have a public default (i.e. no-argument) constructor
have a getter and a setter for each property you want to serialize (a getter for serialization and a setter for deserialization).
As a side note, if you want to keep the getter/setter but don't want to serialize the attribute, things get slightly more complicated with the use of introspection:
// 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);
}
}
Upvotes: 1
Reputation: 49321
XMLEncoder encodes 'Java Beans'. It has no awareness of the fields; it only uses the getters and setters. If there was a 'loop' then it would use xml:id
and xml:idref
to handle the references.
Upvotes: 2