我目前正在开发一个需要持久保存任何类型对象的项目(我们没有任何控制权的实现),因此可以在之后恢复这些对象。
我们无法实现ORM,因为我们无法在开发时限制库的用户。
我们的第一个选择是使用Java默认序列化对其进行序列化,但是当用户开始传递同一对象的不同版本(属性更改的类型,名称......)时,我们在恢复对象时遇到了很多麻烦。 / p>
我们已尝试使用XMLEncoder类(将对象转换为XML),但我们发现缺少功能(例如,不支持Enums)。
最后,我们还尝试了JAXB,但这会强制我们的用户注释他们的类。
有什么好的选择吗?
答案 0 :(得分:39)
2011年,在商业级REST Web服务项目中,我们使用以下序列化程序为客户提供各种媒体类型:
我们最近尝试了其他序列化程序:
Jackson JSON,Kryo和Jackson Smile都比旧的Java对象序列化快得多,大约3倍到4.5倍。 XStream很慢。但在这一点上,这些都是可靠的选择。我们将继续监控其他三个。
答案 1 :(得分:19)
http://x-stream.github.io/很好,请看一下!非常方便
答案 2 :(得分:14)
我们没有任何控制的实施
解决方案不要这样做。如果您无法控制类型的实现,则不应将其序列化。故事结局。 Java序列化提供了serialVersionUID,专门用于管理不同版本的类型之间的序列化不兼容性。如果您不控制实现,则在开发人员更改类时无法确定ID是否正确更改。
举一个'点'的简单例子。它可以用笛卡尔坐标系或极坐标系表示。构建一个能够动态应对这些修正的系统将是成本过高的 - 它必须是设计序列化的类的开发人员。
简而言之,这是你的设计错了 - 而不是技术。
答案 3 :(得分:9)
你最容易做的事情仍然是使用序列化,IMO,但更多地考虑类的序列化形式(无论如何你应该做的)。例如:
序列化表单是API类的一部分,应仔细考虑其设计。
我不会详细介绍很多细节,因为我所说的几乎所有内容都来自Effective Java。我会转而推荐你,特别是有关序列化的章节。它会警告您遇到的所有问题,并为问题提供正确的解决方案:
http://www.amazon.com/Effective-Java-2nd-Joshua-Bloch/dp/0321356683
话虽如此,如果您仍在考虑非序列化方法,请参阅以下内容:
XML编组
许多人已经指出这是一个选项,但我认为你仍会遇到向后兼容性相同的问题。但是,使用XML编组,您可能会立即捕获这些内容,因为某些框架可能会在初始化期间为您进行一些检查。
转换为/来自YAML
这是我一直在想的一个想法,但我真的很喜欢YAML格式(至少作为自定义toString()格式)。但实际上,唯一不同的是你要编组YAML而不是XML。唯一的好处是YAML比XML更具人性化。同样的限制也适用。
答案 4 :(得分:9)
协议缓冲区的一个优点是它可以与C,C ++,python和java交换信息。
答案 5 :(得分:5)
尝试使用Gson序列化为json。
答案 6 :(得分:5)
另一种非常快速的JDK序列化替代品: http://ruedigermoeller.github.io/fast-serialization/
答案 7 :(得分:3)
如果序列化速度对您很重要,那么这里有一个全面的JVM序列化基准:
答案 8 :(得分:1)
可能Castor?
答案 9 :(得分:1)
就个人而言,我经常使用Fame,因为它具有与Smalltalk(包括VW和Squeak)和Python的互操作性。 (免责声明,我是Fame项目的主要贡献者。)
答案 10 :(得分:1)
Betwixt是一个很好的用于序列化对象的库 - 但它不会是一种自动的东西。如果您必须序列化的对象数量相对固定,这对您来说可能是一个不错的选择,但如果您的“客户”将一直向您抛出新课程,则可能需要付出更多努力(对于所有特殊情况,绝对比XMLEncoder更容易。
另一种方法是要求您的客户为他们抛出的任何对象提供相应的.betwixt文件(这有效地将责任转移给他们)。
长短 - 序列化是 hard - 没有完全脑死亡的方法。 Java序列化与我所见过的脑死亡解决方案非常接近,但正如您所发现的,不正确使用版本的uid值可能会破坏它。 Java序列化还需要使用标记'Serializable'接口,所以如果你无法控制你的源代码,那你就有点不幸了。
如果要求真的像你描述的那样艰巨,你可能不得不在对象/方面/其他方面采用某种BCE(字节代码修改)。这远远超出了一个小型开发项目的领域,进入了Hibernate,Casper或ORM领域....
答案 11 :(得分:0)
另一个想法:使用缓存。缓存为应用程序提供了更好的控制,可伸缩性和健壮性。但仍需要序列化,但在缓存服务框架内管理变得更容易。缓存可以保存在内存,磁盘,数据库或阵列中 - 或者所有选项中 - 其中一个是溢出,待机,另一个是故障转移。 Commons JCS和Ehcache是两个java实现,后者是一个免费存储高达32 GB的企业解决方案(免责声明:我不适用于ehcache ;-))。
答案 12 :(得分:0)
SBE是一个已建立的库,用于基于字节缓冲区的快速序列化库,并且能够进行版本控制。但是,使用它有点困难,因为您需要在上面编写长度包装器类。
鉴于其缺点,我最近制作了一个受SBE和FIX协议(用于交换交易/报价消息的通用金融市场协议)启发的纯Java序列化库,该库试图在克服两者的同时保持两者的优势弱点。您可以看看https://github.com/iceberglet/anymsg