对象与XML的互相转换,向前和向后兼容性

8
我正在处理一个应用程序,我们需要将对象保存为XML格式,并在需要时加载它们。为此,我使用了JAXB将XML转换为Java类,反之亦然。
我的问题是,有时我必须更改Java模型(添加、重命名或删除属性),结果就是我会得到不兼容的已保存XML文件,无法绑定到新的类形式中。
为了解决这个问题,在每次更改之前,我会将所有的类复制到一个新的包下(以其版本命名),并应用所需的更改。当保存XML时,我会保存其版本号,以便我可以决定JAXB应该扫描哪个包来解组这个XML。
我的问题是,是否有其他方法使用JAXB实现向前和向后兼容性?如果没有,是否有其他技术能够支持这种功能呢?

1
我担心未来模型结构会发生变化,现在唯一能想到的与旧版本兼容的方法是保留旧类,但这看起来不太好也不实用。您能建议如何处理这种情况吗?我需要将对象持久化为XML格式,并能够再次加载它... - Transient
2个回答

5

注意:我是JAXB 2 (JSR-222)专家组成员和EclipseLink JAXB (MOXy)领导。

对于这种情况,我更倾向于在可能的情况下使用单一模型。这需要您为对象模型编写多个映射。JAXB规范没有提供这样做的方法,但可以使用MOXy的外部元数据扩展来实现:

元数据可以用来补充注释,也可以用来替换它们。因此,我建议用注释映射基本架构,并使用XML格式根据架构版本修改元数据。

我的问题是,我有时需要更改Java model(添加、重命名或删除属性),结果会有不兼容的保存的XML,不能绑定到新类表单。

删除Java属性(字段/属性)会使事情变得困难,因为旧的XML将没有东西可以映射到。相反,您可以在模型中保留它们,并在XML元数据文件中标记为“@XmlTransient”。


谢谢Blaise,我正在尝试应用您的建议,但我想知道MoXy是否可以提供类似于以下内容的支持: Class A { @Override @XmlElements({ @XmlElement(name = "B1", type = B1.class), @XmlElement(name = "B2", type = B2.class) }) List<B> list; }interface B{}class B1 implements B {} class B2 implements B {}以支持接口类型的列表? - Transient
1
鉴于答案相当古老,这仍然是解决问题的最佳方法吗? - Paolo Fulgoni

1
如果你只是添加新属性,它仍然可以工作:这被称为“鸭子类型”。你的对象可以自由地忽略它不需要的额外内容。
只有在修改或删除必需的属性时才需要担心版本控制。不幸的是,这适用于数据库模式、Java序列化和任何其他持久性技术。XML并不神奇;它也不免疫。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接