[英]JAXB and different versions of the class
我想知道在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个不同的类表示,但仍然可以将它们映射到运行时中可用的类的版本。
如果您使用的是JAXB,那么您将持久化xml而不是Java对象。 如果你是持久化java对象,它将是序列化。 Jaxb转换尝试将xml值绑定到类属性。 只要转换先决条件有效,就不会有问题。 其他库如JIBX,尝试直接访问字节码。 在这种情况下,类版本可能是一个问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.