XML-сериализация в Java? [закрыто]

104

Что представляет собой Java-аналог сериализации XML в .NET?

Дмитрий Шехтман
источник
7
Ах, славные старые времена, когда однострочные вопросы, подобные этому, приветствовались на SO. Так полезно. Без всего этого бреда типа «Что ты пробовал?» / «Расскажите подробнее» люди любят читать сегодня.
GOTO 0

Ответы:

81

Ответ 2008 г. «Официальным» Java API для этого теперь является JAXB - Java API для привязки XML. См. Учебник Oracle . Эталонная реализация находится по адресу http://jaxb.java.net/

Обновление 2018 Обратите внимание, что модули Java EE и CORBA устарели в SE в JDK9 и должны быть удалены из SE в JDK11 . Следовательно, чтобы использовать JAXB, он должен быть либо в вашей существующей среде корпоративного класса, связанной, например, с вашим сервером приложений, либо вам нужно будет ввести его вручную.

Cheekysoft
источник
2
Правильно, JAXB определенно лучший вариант!
ivan_ivanovich_ivanoff
1
JAXB был удален из стандартных java-дистрибутивов, начиная с Java 10, что делает его теперь библиотекой, которую вы должны связать с вашим приложением, если хотите, если вы не работаете в контексте, который уже связывает его для вас.
Теодор Мердок
69

XStream довольно хорошо сериализует объект в XML без особых настроек и денег! (это под лицензией BSD).

Мы использовали его в одном из наших проектов, чтобы заменить простую старую java-сериализацию, и он работал почти сразу же.

Барак Шиллер
источник
3
Очень полезно, но могут возникнуть проблемы с завершенными древовидными структурами, такими как JGraph, с объектами, не являющимися строковыми узлами.
mikek3332002 03
Проще и лучше, чем другие решения
daitangio
Мне нравится XStream. Единственное, что я не понимаю, почему символ добавляется перед фактическим XML.
Джеймс П.
17

Проект "Простая сериализация XML"

Вы можете взглянуть на проект Simple XML Serialization . Это самое близкое, что я нашел к System.Xml.Serialization в .Net.

АРКБАН
источник
Однако для каждого поля требуются аннотации сопоставления.
М.П.
1
Неправда, мне не нужно. Вы можете изменить поведение по умолчанию, и оно будет использовать только существующие поля.
damluar
1
Я также искренне поддерживаю "Простой" . Я успешно использовал его в нескольких проектах. «Простой» действительно намного проще, чем JAXB. Наиболее подходит, когда у вас относительно простые потребности: есть объекты, которые нужно записать в хранилище, чтобы впоследствии снова преобразовать их в объекты. JAXB имеет гораздо больше возможностей и гибкости, но это тип «80/20», большую часть времени в большинстве проектов вам может понадобиться только простое подмножество функций.
Basil Bourque
Хорошо работает, если вам просто нужно отображение 1: 1. Если ваши классы развиваются, а вам все еще нужно десериализовать старый XML, вы столкнетесь с проблемами, потому что и документация, и сообщения об ошибках несколько расплывчаты. Диагностировать проблему обычно можно, но выяснение того, как ее исправить, может занять несколько дней.
toolforger
13

JAXB является частью стандартной версии JDK 1.6+. Так оно и есть, FREEи никаких дополнительных библиотек для загрузки и управления. Простой пример можно найти здесь

XStream вроде мертв. Последнее обновление было 6 декабря 2008 г. Simpleкажется таким же простым и простым, как JAXB, но я не смог найти никакой информации о лицензировании, чтобы оценить его для корпоративного использования.

so_mv
источник
4
XStream не мертв, он просто зрелый и стабильный, а это означает, что нечего добавить к основным функциям. То же самое верно и для эталонной реализации JAXB, за последние пару лет активности не было.
StaxMan
9

Стоит отметить, что начиная с версии 1.4 в Java были классы java.beans.XMLEncoder и java.beans.XMLDecoder. Эти классы выполняют кодирование XML, которое, по крайней мере, очень сравнимо с сериализацией XML и в некоторых случаях может помочь вам.

Если ваш класс придерживается спецификации JavaBeans для своих геттеров и сеттеров, этот метод прост в использовании и вам не нужна схема. Со следующими оговорками:

  • Как и при обычной сериализации Java
    • кодирование и декодирование выполняются через InputStream и OutputStream
    • процесс использует известные методы writeObject и readObject
  • В отличие от обычной сериализации Java
    • кодирование, но также и декодирование вызывают вызов конструкторов и инициализаторов
    • кодирование и декодирование работают независимо от того, реализует ли ваш класс Serializable или нет
    • переходные модификаторы не учитываются
    • работает только для публичных классов, у которых есть публичные конструкторы

Например, возьмите следующее объявление:

public class NPair {
  public NPair() { }
  int number1 = 0;
  int number2 = 0;
  public void setNumber1(int value) { number1 = value;}
  public int getNumber1() { return number1; }
  public void setNumber2(int value) { number2 = value; }
  public int getNumber2() {return number2;}
}

Выполнение этого кода:

NPair fe = new NPair();
fe.setNumber1(12);
fe.setNumber2(13);
FileOutputStream fos1 = new FileOutputStream("d:\\ser.xml");
java.beans.XMLEncoder xe1 = new java.beans.XMLEncoder(fos1);
xe1.writeObject(fe);
xe1.close();

Результатом будет следующий файл:

<?xml version="1.0" encoding="UTF-8"?>
<java version="1.7.0_02" class="java.beans.XMLDecoder">
 <object class="NPair">
  <void property="number1">
   <int>12</int>
  </void>
  <void property="number2">
   <int>13</int>
  </void>
 </object>
</java>
Мишакс
источник
Имейте в виду, что использование java.beans.XMLDecoderданных, предоставленных пользователем, может привести к уязвимости выполнения произвольного кода в вашем коде.
авантюрин
2

XMLBeans отлично работает, если у вас есть схема для XML. Он создает объекты Java для схемы и создает простые в использовании методы синтаксического анализа.

Джон Мигер
источник
0

Если вы говорите об автоматической XML-сериализации объектов, посмотрите Castor :

Castor - это среда привязки данных с открытым исходным кодом для Java [tm]. Это кратчайший путь между объектами Java, документами XML и реляционными таблицами. Castor обеспечивает привязку Java-to-XML, постоянство Java-to-SQL и многое другое.

Тео
источник
0

Обычно я использую jaxb или XMLBeans, если мне нужно создать объекты, сериализуемые в XML. Теперь я вижу, что XStream может быть очень полезным, поскольку он ненавязчив и имеет очень простой api. Я скоро поиграю с ним и, наверное, воспользуюсь. Единственный недостаток, который я заметил, - это то, что я не могу самостоятельно создать идентификатор объекта для перекрестных ссылок.

@Barak Schiller
Спасибо, что разместили ссылку на XStream!

Бартош Берковски
источник
Проблема в том, что jaxb и xmlbeans требуют схемы сопоставления и не авто ...
mP.
0

если вам нужно структурированное решение (например, ORM), тогда JAXB2 - хорошее решение.

Если вам нужна сериализация, такая как DOT NET, вы можете использовать долгосрочное сохранение компонентов JavaBeans

Выбор зависит от использования сериализации.

м.генова
источник
-1
public static String genXmlTag(String tagName, String innerXml, String properties )
{
    return String.format("<%s %s>%s</%s>", tagName, properties, innerXml, tagName);
}

public static String genXmlTag(String tagName, String innerXml )
{
    return genXmlTag(tagName, innerXml, "");
}

public static <T> String serializeXML(List<T> list)
{
    String result = "";
    if (list.size() > 0)
    {
        T tmp = list.get(0);
        String clsName = tmp.getClass().getName();
        String[] splitCls = clsName.split("\\.");
        clsName = splitCls[splitCls.length - 1];
        Field[] fields = tmp.getClass().getFields();

        for (T t : list)
        {
            String row = "";
            try {
                for (Field f : fields)
                {
                    Object value = f.get(t);
                    row += genXmlTag(f.getName(), value == null ? "" : value.toString());
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            row = genXmlTag(clsName, row);

            result += row;
        }
    }

    result = genXmlTag("root", result);
    return result;
}
user4067649
источник
Множество проблем: Переосмысление класса # getSimpleName *** Переосмысление PropertyDescriptor *** Предполагается, что все свойства являются доступными полями *** Не кэширует результаты отражения (slooow) *** Нет возможности настроить что-либо (например, мне нужно было бы заменить имена классов и файлов) *** Без десериализации
toolforger