Какая лучшая альтернатива для сериализации Java? - PullRequest
45 голосов
/ 27 октября 2008

В настоящее время я работаю над проектом, который должен сохранять любой тип объекта (реализация которого мы не имеем никакого контроля), чтобы впоследствии эти объекты могли быть восстановлены.

Мы не можем реализовать ORM, потому что мы не можем ограничивать пользователей нашей библиотеки во время разработки.

Наша первая альтернатива заключалась в том, чтобы сериализовать его с использованием сериализации по умолчанию на Java, но у нас было много проблем с восстановлением объектов, когда пользователи начали передавать разные версии одного и того же объекта (атрибуты изменяли типы, имена, ...). 1005 *

Мы пробовали с классом XMLEncoder (преобразует объект в XML), но обнаружили, что отсутствует функциональность (например, не поддерживает Enums).

Наконец, мы также попробовали JAXB, но это заставляет наших пользователей комментировать свои классы.

Любая хорошая альтернатива?

Ответы [ 13 ]

39 голосов
/ 14 марта 2011

Это 2011 год, и в проекте веб-сервисов REST коммерческого уровня мы используем следующие сериализаторы, чтобы предлагать клиентам различные типы носителей:

  • XStream (для XML, но не для JSON)
  • Джексон (для JSON)
  • Kryo (быстрый, компактный двоичный формат сериализации)
  • Smile (двоичный формат, который поставляется с Jackson 1.6 и более поздними версиями).
  • Сериализация объектов Java.

Недавно мы экспериментировали с другими сериализаторами:

  • SimpleXML кажется надежным, работает в 2 раза быстрее XStream, но требует слишком большой конфигурации для нашей ситуации.
  • YamlBeans было несколько ошибок.
  • SnakeYAML была небольшая ошибка, связанная с датами.

Jackson JSON, Kryo и Jackson Smile были значительно быстрее, чем старая добрая сериализация Java-объектов, примерно в 3–4 раза. XStream на медленной стороне. Но это все солидный выбор на данный момент. Мы продолжим следить за остальными тремя.

19 голосов
/ 27 октября 2008

http://x -stream.github.io / приятно, пожалуйста, посмотрите на это! Очень удобно

14 голосов
/ 27 октября 2008

реализации которого мы не имеем никакого контроля

Решение не делайте этого . Если у вас нет контроля над реализацией типа, вам не следует его сериализовывать. Конец истории. Сериализация Java предоставляет serialVersionUID специально для управления несовместимостью сериализации между различными версиями типа. Если вы не контролируете реализацию, вы не можете быть уверены, что идентификаторы меняются правильно, когда разработчик меняет класс.

Возьмите простой пример «Точки». Он может быть представлен либо декартовой, либо полярной системой координат. Вам было бы непозволительно дорого создать систему, которая могла бы динамически справляться с такого рода исправлениями - это действительно должен быть разработчик класса, который разрабатывает сериализацию.

Короче говоря, это ваш дизайн, а не технология.

9 голосов
/ 28 октября 2008

Google разработал двоичный протокол - http://code.google.com/apis/protocolbuffers/ быстрее, имеет меньшую полезную нагрузку по сравнению с XML - что другие предложили в качестве альтернативы.

Одним из преимуществ буферов протокола является то, что он может обмениваться информацией с C, C ++, Python и Java.

9 голосов
/ 27 октября 2008

Самое простое, что вам нужно сделать, - это по-прежнему использовать сериализацию, IMO, но уделить больше внимания сериализованной форме классов (что вам действительно следует делать в любом случае). Например:

  1. Явно определите SerialUID.
  2. Определите вашу собственную сериализованную форму, где это необходимо.

Сериализованная форма является частью API класса, и ее дизайн должен быть тщательно продуман.

Я не буду вдаваться в подробности, так как почти все, что я сказал, происходит из Effective Java. Вместо этого я отсылаю вас к нему, в частности к главам о сериализации. Он предупреждает вас обо всех проблемах, с которыми вы сталкиваетесь, и предоставляет правильные решения проблемы:

http://www.amazon.com/Effective-Java-2nd-Joshua-Bloch/dp/0321356683


С учетом сказанного, если вы все еще рассматриваете подход без сериализации, вот пара:

XML-сортировка

Как уже указывалось многими, это вариант, но я думаю, что вы все равно столкнетесь с теми же проблемами с обратной совместимостью. Однако, с помощью XML-маршалинга, мы надеемся, вы сразу же поймете это, поскольку некоторые фреймворки могут выполнять некоторые проверки во время инициализации.

Преобразование в / из YAML

Это идея, с которой я играю, но мне очень понравился формат YAML (по крайней мере, как пользовательский формат toString ()). Но на самом деле единственное отличие для вас состоит в том, что вы будете использовать YAML вместо XML. Единственное преимущество заключается в том, что YAML немного более удобочитаем, чем XML. Применяются те же ограничения.

5 голосов
/ 07 декабря 2012

Также очень быстрая замена вставки в сериализацию JDK: http://ruedigermoeller.github.io/fast-serialization/

5 голосов
/ 27 октября 2008

Попробуйте сериализовать в json, например, Gson .

3 голосов
/ 16 июля 2013

Если вам важна скорость сериализации, то здесь есть исчерпывающий тест для сериализаторов JVM:

1 голос
/ 28 октября 2008

Betwixt - хорошая библиотека для сериализации объектов, но это не будет автоматом. Если количество объектов, которые вы должны сериализовать, относительно фиксировано, это может быть хорошим вариантом для вас, но если ваш «клиент» будет все время бросать вам новые классы, это может потребовать больше усилий, чем стоит ( Определенно проще, чем XMLEncoder для всех особых случаев, хотя).

Другой подход заключается в том, чтобы потребовать от вашего клиента предоставления соответствующих файлов .betwixt для любых объектов, которые они вам бросают (что эффективно снимает с них ответственность).

Длинная и короткая - сериализация жесткая - нет абсолютно мертвого подхода к этому. Сериализация Java так же близка к мертвому решению, как я когда-либо видел, но, как вы обнаружили, неправильное использование значения версии uid может сломать его. Сериализация Java также требует использования интерфейса маркера «Serializable», поэтому, если вы не можете контролировать свой источник, вам не повезло с этим.

Если требование действительно столь же сложно, как вы описываете, вам, возможно, придется прибегнуть к некоторому BCE (модификации байтового кода) для объектов / аспектов / чего угодно. Это выходит за рамки небольшого проекта разработки и попадает в сферу Hibernate, Casper или ORM ....

1 голос
/ 27 октября 2008

Лично я очень часто пользуюсь Fame , поскольку он поддерживает взаимодействие с Smalltalk (как VW, так и Squeak) и Python. (Отказ от ответственности, я основной вкладчик проекта Fame.)

...