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

时间:2015-12-11 17:51:27

标签: java xml jaxb xstream

我是一个负责编写新版软件包的团队。旧版本使用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

我不确定这是否完全符合我的要求,但这是我关注的一部分。我们不确定我们知道我们想要什么样的数据模型,也不能确定我们将来不会再次改变它。我不只是添加,删除或重命名对象:我想移动/复制它们。

当向后兼容性不是问题时,Xstream和JAXB非常适合序列化对象。 XStream有一个FAQ描述了简单修改的​​解决方案,但我想知道他们是否建议实施自己的转换器"对于足够复杂的情况意味着我应该完全跳过xstream。其他人提出了related个问题。

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

1 个答案:

答案 0 :(得分:0)

我给了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在这种特定情况下给我带来了什么。