Java JAXB和该类的不同版本

Java JAXB和该类的不同版本,java,xml-serialization,jaxb,xml-deserialization,Java,Xml Serialization,Jaxb,Xml Deserialization,我想知道JAXB中是否支持类的不同版本。 我的想法是:xml是类的持久化对象(序列化值),但类对象可以因开发而更改(例如扩展功能)。有没有办法只使用JAXB API就知道类的哪个版本存储在持久性(read:xml)中 对我来说,存储类版本似乎很方便——就像在标准java序列化机制中一样(我指的是serialVersionUID),并提供在类上映射xml的功能,即使是在不同版本的情况下(例如,添加关于存储在xml中的类的版本的XmlAdapter信息)。默认情况下,若类在xml和运行时中的版本不同

我想知道JAXB中是否支持类的不同版本。 我的想法是:xml是类的持久化对象(序列化值),但类对象可以因开发而更改(例如扩展功能)。有没有办法只使用JAXB API就知道类的哪个版本存储在持久性(read:xml)中

对我来说,存储类版本似乎很方便——就像在标准java序列化机制中一样(我指的是serialVersionUID),并提供在类上映射xml的功能,即使是在不同版本的情况下(例如,添加关于存储在xml中的类的版本的XmlAdapter信息)。默认情况下,若类在xml和运行时中的版本不同,则抛出InvalidClassException

例如: 我们的课堂测试如下:

@XmlRootElement
@XmlAccessorType(value = XmlAccessType.FIELD)
public class Test {

    private Long time;

    private Test () {}; 
}
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;
}
假设时间是UNIX时间,单位为毫秒

这段代码是在生产环境中发布的,这个类作为xml保存在数据库中。 下一版本显示,使用长时间表示法不是一个好选择,它已更改为最新版本:

@XmlRootElement
@XmlAccessorType(value = XmlAccessType.FIELD)
public class Test {

    private Date time;

    private Test () {}; 
}
现在有两种方法——要么迁移持久化数据,要么编写xml适配器来处理较长的时间并将其应用于日期时间

如果我们选择第二种方式,如果JAXB API提供以xml格式存储的类版本(假设在class=0版本中没有指定类版本),并且我们显式地添加类的新版本(通过注释或通过静态字段):

JAXB将提供如下XmlAdapter:

@XmlRootElement
@XmlAccessorType(value = XmlAccessType.FIELD)
public class Test {

    private Long time;

    private Test () {}; 
}
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;
}
公共抽象类XmlAdapter{
受保护的XmlAdapter(){}
公共抽象BoundType unmarshal(ValueType v,long classVersion)抛出异常;
公共抽象值类型封送(BoundType v,long classVersion)抛出异常;
}
当然,为了支持多个版本,我们需要实现这样的适配器并显式地处理不同的版本。 显然,JAXB将在xml中添加关于类的特殊信息,并在最新的类版本上生成xml


注意:上面示例的要点是,我们在持久化中同时有2种不同的类表示,但仍然可以将它们映射到运行时可用的类版本。

如果您使用JAXB,您将持久化xml,而不是java对象。如果您是持久化java对象,那么它将是序列化。Jaxb转换尝试将xml值绑定到类属性。只要转换先决条件起作用,就不会有问题。其他库,如JIBX,尝试直接访问字节码。在这种情况下,类版本可能是一个问题。

JAXB代表“用于XML绑定的Java体系结构”,因此,它是关于将对象字段值绑定到XML元素/属性,而不是关于序列化Java对象。例如,在你读到这个例子时,你会看到它说

bind,包含用于执行 解组、编组和验证等操作


Java对象序列化是另一回事,它与您在问题中提到的
serialVersionUID
相关。

但是如果我们使用JAX WS作为Web服务实现,那么-JAXB API=序列化API。这句话对吗?据我所知,JAX WS使用
xjc:serializable
来覆盖实现
java.io.serializable
的类的绑定。查看文章并搜索“xjc:serializable”。