我目前正在开发一个项目,它需要持久保存任何类型的对象(我们没有任何控制权的实现),因此这些对象可以在之后恢复.
我们无法实现ORM,因为我们无法在开发时限制库的用户.
我们的第一个选择是使用Java默认序列化对其进行序列化,但是当用户开始传递同一对象的不同版本(属性更改类型,名称等)时,我们在恢复对象时遇到了很多麻烦.
我们尝试过使用XMLEncoder类(将对象转换为XML),但我们发现缺少功能(例如,不支持Enums).
最后,我们还尝试了JAXB,但这会强制我们的用户注释他们的类.
还有什么好办法吗
这是2011年,在商业级REST Web服务项目中,我们使用以下序列化器为客户提供各种媒体类型:
XStream(适用于XML但不适用于JSON)
杰克逊(JSON)
Kryo(一种快速,紧凑的二进制序列化格式)
微笑(Jackson 1.6及更高版本附带的二进制格式).
Java对象序列化.
我们最近尝试了其他序列化程序:
SimpleXML似乎很稳定,运行速度是XStream的2倍,但对于我们的情况需要一些配置太多.
YamlBeans有几个错误.
SnakeYAML有一个与日期有关的小错误.
杰克逊JSON,Kryo和杰克逊微笑都比旧的Java对象序列化快得多,大约3倍到4.5倍.XStream很慢.但在这一点上,这些都是可靠的选择.我们将继续监控其他三个.
http://x-stream.github.io/很好,请看一下!很方便
其实施我们没有任何控制权
解决方案是不要这样做.如果您无法控制类型的实现,则不应将其序列化.故事结局.Java序列化提供了serialVersionUID,专门用于管理不同版本的类型之间的序列化不兼容性.如果您不控制实现,则在开发人员更改类时无法确定ID是否正确更改.
举一个'点'的简单例子.它可以用笛卡尔坐标系或极坐标系表示.构建一个可以动态应对这些修正的系统将是成本过高的 - 它实际上必须是设计序列化的类的开发人员.
简而言之,这是你的设计错了 - 而不是技术.
你要做的最简单的事情仍然是使用序列化,IMO,但更多地考虑类的序列化形式(无论如何你应该做的).例如:
明确定义SerialUID.
在适当的地方定义您自己的序列化表格.
序列化表单是API类的一部分,应仔细考虑其设计.
我不会详细介绍,因为我所说的几乎所有内容都来自Effective Java.我会转而推荐你,特别是有关序列化的章节.它会警告您遇到的所有问题,并为问题提供正确的解决方案:
http://www.amazon.com/Effective-Java-2nd-Joshua-Bloch/dp/0321356683
话虽如此,如果您仍在考虑非序列化方法,这里有几个:
XML编组
正如许多人所指出的那样是一种选择,但我认为你仍然会遇到向后兼容性问题.但是,使用XML编组,您可能会立即捕获这些内容,因为某些框架可能会在初始化期间为您进行一些检查.
转换到/来自YAML
这是我一直在想的一个想法,但我真的很喜欢YAML格式(至少作为自定义toString()格式).但实际上,唯一不同的是你要编组YAML而不是XML.唯一的好处是YAML比XML更具人性化.同样的限制适用.
谷歌想出了一个二进制协议 - http://code.google.com/apis/protocolbuffers/速度更快,与XML相比有更小的负载 - 其他人建议将其作为替代协议.
协议缓冲区的一个优点是它可以与C,C++,python和java交换信息.
例如,尝试使用Gson序列化为json .
也是一个非常快速的JDK序列化替代品:http: //ruedigermoeller.github.io/fast-serialization/