3

有一个类可以很好地序列化为带有 XMLEncoder 的 xml 中的所有变量。除了拥有java.util.Locale的那个。可能是什么诀窍?

4

2 回答 2

8

问题是 java.util.Locale 不是bean。来自XMLEncoder文档:

XMLEncoder 类是 ObjectOutputStream 的补充替代品,可用于生成 JavaBean的文本表示,就像 ObjectOutputStream 可用于创建可序列化对象的二进制表示一样。

但是,API 允许您使用 PersistenceDelegates 来序列化非 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;
    }

}

序列化包含 Locale 类型的数据图:

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

}

这是描述在反序列化时如何实例化对象的代码部分 - 它将构造函数参数设置为三个字符串值:

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

阅读Philip Milne 的Using XMLEncoder了解更多信息。

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.

于 2008-10-12T16:57:25.170 回答
0

对不起,你不是说java.util.Locale吗?javadocs 说java.util.Locale实现了Serializable ,因此使用lang包中的Locale类应该没有问题。

于 2008-10-12T16:14:50.653 回答