Got a class that serializes into xml with XMLEncoder nicely with all the variables there. Except for the one that holds java.util.Locale. What could be the trick? TIA.
Sorry, don't you mean java.util.Locale? The javadocs say that java.util.Locale implements Serializable, so you should have no problem using the Locale class from the lang package.
The problem is that java.util.Locale is not a bean. From the XMLEncoder doc:
The XMLEncoder class is a complementary alternative to the ObjectOutputStream and can used to generate a textual representation of a JavaBean in the same way that the ObjectOutputStream can be used to create binary representation of Serializable objects.
However, the API allows you to use PersistenceDelegates to serialize non-bean types:
Sample bean:
public class MyBean implements Serializable {
private static final long serialVersionUID = 1L;
private Locale locale;
private String foo;
public MyBean() {
}
public Locale getLocale() {
return locale;
}
public void setLocale(Locale locale) {
this.locale = locale;
}
public String getFoo() {
return foo;
}
public void setFoo(String foo) {
this.foo = foo;
}
}
Serializing a data graph that includes a Locale type:
public class MyBeanTest {
public static void main(String[] args) throws Exception {
// quick and dirty test
MyBean c = new MyBean();
c.setLocale(Locale.CHINA);
c.setFoo("foo");
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
XMLEncoder encoder = new XMLEncoder(outputStream);
encoder.setPersistenceDelegate(Locale.class, new PersistenceDelegate() {
protected Expression instantiate(Object oldInstance, Encoder out) {
Locale l = (Locale) oldInstance;
return new Expression(oldInstance, oldInstance.getClass(),
"new", new Object[] { l.getLanguage(), l.getCountry(),
l.getVariant() });
}
});
encoder.writeObject(c);
encoder.flush();
encoder.close();
System.out.println(outputStream.toString("UTF-8"));
ByteArrayInputStream bain = new ByteArrayInputStream(outputStream
.toByteArray());
XMLDecoder decoder = new XMLDecoder(bain);
c = (MyBean) decoder.readObject();
System.out.println("===================");
System.out.println(c.getLocale());
System.out.println(c.getFoo());
}
}
This is the section of code that describes how the object should be instantiated on deserialization - it sets the constructor arguments to three string values:
new PersistenceDelegate() {
protected Expression instantiate(Object oldInstance, Encoder out) {
Locale l = (Locale) oldInstance;
return new Expression(oldInstance, oldInstance.getClass(),
"new", new Object[] { l.getLanguage(), l.getCountry(),
l.getVariant() });
}
}
Read Using XMLEncoder by Philip Milne for more info.
All this aside, it might be smarter to store the locale information in textual form and use it to look up the appropriate Locale object whenever it is needed. That way you don't need special case code when serializing your object and make it more portable.
This is a nice article in which its tell you how implement setPersistenceDelegate.