Сериализация java.lang.Locale - PullRequest
       12

Сериализация java.lang.Locale

2 голосов
/ 12 октября 2008

Получил класс, который сериализовался в xml с XMLEncoder, со всеми имеющимися переменными. За исключением того, что содержит java.util.Locale . В чем может быть подвох?

Ответы [ 2 ]

7 голосов
/ 12 октября 2008

Проблема в том, что java.util.Locale не является bean . Из XMLEncoder документ:

Класс XMLEncoder является дополнительная альтернатива ObjectOutputStream и может использоваться для генерировать текстовое представление JavaBean так же, как ObjectOutputStream может быть использован для создать двоичное представление Сериализуемые объекты.

Однако API позволяет использовать PersistenceDelegates для сериализации типов, не относящихся к компонентам:

Пример боба:

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

Чтение Использование XMLEncoder от Philip Milne для получения дополнительной информации.

Помимо всего этого, может быть разумнее хранить информацию о локали в текстовой форме и использовать ее для поиска соответствующего объекта локали, когда это необходимо. Таким образом, вам не понадобится специальный регистр кода при сериализации вашего объекта и сделать его более переносимым.

0 голосов
/ 12 октября 2008

Извините, вы не имеете в виду java.util.Locale ? Javadocs говорят, что java.util.Locale реализует Serializable , поэтому у вас не должно возникнуть проблем с использованием класса Locale из пакета lang .

...