我想知道在JAXB中是否支持不同版本的类。 我的想法:xml是类的一种持久性对象(序列化值),但是由于开发(例如扩展功能),类对象可以被改变。有没有办法知道只使用JAXB API在持久性(read:xml)中存储哪个版本的类?
对我来说,存储类版本似乎很方便 - 就像它在标准java序列化机制(我的意思是serialVersionUID)中所做的那样,并提供在类上映射xml的功能,即使在不同版本的情况下(例如添加关于类的版本的XmlAdapter信息)存储在xml中)。默认情况下,如果xml和运行时中的类版本不同 - 抛出InvalidClassException。
实施例: 我们的课程考试如下:
@XmlRootElement
@XmlAccessorType(value = XmlAccessType.FIELD)
public class Test {
private Long time;
private Test () {};
}
假设时间是以毫秒为单位的UNIX时间。
此代码在生产时发布,此类作为xml保存在数据库中。 下一个版本显示使用Long作为时间表示并且它已更改为Date:
不是一个好选择@XmlRootElement
@XmlAccessorType(value = XmlAccessType.FIELD)
public class Test {
private Date time;
private Test () {};
}
现在有两种方法 - 迁移持久化数据或编写xml适配器,它将处理长时间并将其应用于日期时间。
如果我们选择第二种方式,那么如果JAXB API提供存储在xml中的类版本(假设在class = 0版本中没有指定类版本)并且我们明确地添加新版本的类(通过注释)将是很好的或静态字段):
@XmlRootElement
@XmlAccessorType(value = XmlAccessType.FIELD)
@XmlClassVersion(value = 1)
public class Test {
private Date time;
private Test () {};
}
或
@XmlRootElement
@XmlAccessorType(value = XmlAccessType.FIELD)
public class Test {
private static final long xmlSerialVersionUID = 1;
private Date time;
private Test () {};
}
和JAXB将提供如下的XmlAdapter:
public abstract class XmlAdapter<ValueType,BoundType> {
protected XmlAdapter() {}
public abstract BoundType unmarshal(ValueType v, long classVersion) throws Exception;
public abstract ValueType marshal(BoundType v, long classVersion) throws Exception;
}
当然,为了支持多个版本,我们需要实现这样的适配器并明确地处理不同的版本。 显然,JAXB将在xml中添加有关类的特殊信息,并将在最新的类版本上生成xml。
注意:上面示例中的点我们在持久性中同时有2个不同的类表示,但仍然可以将它们映射到运行时中可用的类的版本。
答案 0 :(得分:1)
JAXB代表&#34; Java架构的XML绑定&#34;,因此,它是关于将对象字段值绑定到XML元素/属性,而不是关于序列化java对象。在您阅读此article时,您会看到它显示
javax.xml.bind,包含用于执行的类和接口 解组,编组和验证等操作
Java对象序列化是另一回事,它与你在问题中提到的serialVersionUID
有关。
答案 1 :(得分:0)
如果您使用的是JAXB,那么您将持久化xml而不是Java对象。如果你是持久化java对象,它将是序列化。 Jaxb转换尝试将xml值绑定到类属性。只要转换先决条件有效,就不会有问题。其他库如JIBX,尝试直接访问字节码。在这种情况下,类版本可能是一个问题。