我可以在多大程度上更改我的数据模型并仍然使用 XStream/JAXB?

How far can I change my data model and still use XStream/JAXB?

我所在的团队负责编写新版本的软件包。旧版本使用 XStream 进行序列化。对于新版本,我们想重新组织数据模型,这反过来又需要一种新格式的输出文件。我们需要支持读取旧的数据格式,而旧的格式不止一种。

例如,在旧版本中,我可能有这个数据结构,其中每个元素都不同(非 POJO)类:

root
    + A
    + B
        + i
        + 1
        + 2

而现在我可能想重构 A 的实例现在是 B 的子实例,并且 i 的内容被拆分并单独移动:

root
    + i.1
    + C
        + i.2
        + B
            + A
            + 1
            + 2
        + B
            + A
            + 1
            + 2

我不确定这是否正是我想要做的,但这是我关注的一部分。我们不确定我们知道我们想要什么数据模型,我们也不能确定我们将来不会再改变它。我不仅仅是添加、删除或重命名对象:我想 move/copy 它们。

Xstream 和 JAXB 非常适合在向后兼容性不是问题的情况下序列化对象。 XStream 有 FAQ describing solutions for simple alterations, but I'm wondering if their recommendation of "implement your own converter" for sufficiently complicated cases implies I should just skip xstream altogether. Other people have asked related 个问题。

我可以使用 xstream/JAXB 来支持将我说明的不同数据格式读取到同一数据模型中吗?我的猜测是没有,因为我太缺乏经验无法确定。

我试了一下 xstream,它成功了。我首先为顶级标签注册一个转换器:

TopLevel topLevel = new TopLevel();
xstream = new XStream(new DomDriver());
xstream.registerConverter(new TopLevelConverter(topLevel));
xstream.alias("TopLevel", TopLevel.class);
xstream.fromXML(data);

并且每个转换器为每个后续类型的节点引入新的转换器,例如在 TopLevelConverter 中:

public Object unmarshal(HierarchicalStreamReader reader,
                        UnmarshallingContext context) {
    while (reader.hasMoreChildren()) {
        reader.moveDown();
        if("SecondLevel".equals(reader.getNodeName())){
            SecondLevel secondLevel =
                (SecondLevel)context.convertAnother(topLevel,
                    SecondLevel.class,
                    new SecondLevelConverter(topLevel));
            topLevel.add(secondLevel);
        }
        reader.moveUp();
    }
    return topLevel;
}

其中 SecondLevelConverter 反过来也调用 convertAnother。通过这种方式,我可以通过转换器的构造函数传递对象来做任何我想做的事情:有时数据向下发送供子级使用,有时更高级别的引用向下发送以便子级转换器可以调用设置方法。

但是,这可能看起来与没有 xstream 时我所做的类似,所以我不确定 xstream 在这种特定情况下给我带来了什么。