如何在运行时告诉JAXB序列化哪些字段?

3

我希望能够根据请求和用户选择性地序列化字段。

例如,管理员用户将获得包含一些额外字段的XML。而普通用户将获得不包含这些字段的XML。

其次,目前我使用@XmlIDREF来防止引用对象或集合的不必要扩展。

但有时用户可能需要这些详细信息。为了避免进行第二个引用对象的请求,我想让用户告诉服务器应该扩展哪个XYZ属性(即包括完整对象而不仅仅是引用)

根据业务逻辑,给定一个用户和一个请求,我可以确定应该序列化哪些字段。现在如何将这些信息传达给JAXB?

尽可能地,我不想创建XSD。请注意,请求参数是动态的。决定序列化哪些字段是在运行时确定的。因此,我不能使用必须硬编码的东西,比如@Transient@XmlIDREF注释。

2个回答

2
注意:我是EclipseLink JAXB (MOXy)的负责人,也是JAXB (JSR-222)专家组的成员。
在EclipseLink 2.5中(可在此处获取:http://www.eclipse.org/eclipselink/downloads/milestones.php),我们为MOXy JAXB添加了一个名为“对象图”的新功能。对象图允许通过编程或元数据选择要进行编组/解组的属性子集。以下是创建对象图以从CustomerAddressPhoneNumber模型获取数据子集的示例。
    // Create the Object Graph
    ObjectGraph contactInfo = JAXBHelper.getJAXBContext(jc).createObjectGraph(Customer.class);
    contactInfo.addAttributeNodes("name");
    Subgraph location = contactInfo.addSubgraph("billingAddress");
    location.addAttributeNodes("city", "province");
    Subgraph simple = contactInfo.addSubgraph("phoneNumbers");
    simple.addAttributeNodes("value");

    // Output XML - Based on Object Graph
    marshaller.setProperty(MarshallerProperties.OBJECT_GRAPH, contactInfo);
    marshaller.marshal(customer, System.out);

更多信息


谢谢,这很好。运作良好。但是我在子图中调度ID字段方面遇到了一些问题。我有一个类A对象的列表(包装在JaxbList中)。每个类A对象都有一个类B对象的列表。我通过传递给JaxbList.class来创建对象图。从那里,我为B创建了一个子图。类A按预期序列化,但是子图的ID字段未被序列化。如果我尝试将B保留为主图(而不是子图)进行编组,则ID字段将按预期序列化。你有什么想法可能是错的吗?我尝试注释掉XmlID注释。它仍然发生。 - Dojo

2
我不会试图深入了解XSD。这是我的建议:
1- 默认情况下,JAXB 不会序列化 null 字段。所以你可以简单地将你不想序列化的字段置为 null。
为了更加清晰,我建议你将你的业务对象的副本设置为 null。这样可以确保在应用程序中没有副作用。
2- 你还可以使用 map 让你的字段变得动态,并存储。这将让你完全控制你的字段的生命周期。
编辑:键将是您的变量名称,值将是您的对象引用。如果您的值应该是原始类型,则可以将您的值自动装箱到相关的对象容器中。JAXB 将序列化 map 中的所有现有值。
如果您必须在多个类之间共享键定义,我建议您将(键,值)的创建/销毁封装到另一个类中。
3- 如果你想强制执行一组特定的属性,它们可以同时为 null 或非 null,并且如果以下抽象对你的应用程序有意义。则你也可以定义具有不同属性的子类的子集。父类将拥有必须具备的属性。
祝你好运。

谢谢。我正在考虑做类似于第一点的事情。但这不是很整洁。比如,对象A引用B。我显然不会在对B的引用上使用XmlIDREF,因为这将阻止B被扩展。但现在当我不想扩展B时,我必须将B的所有字段都设置为null,除了保存ID的字段。不是很漂亮,但可以做到,到目前为止看起来是最好的选择。您能详细说明第二点吗? - Dojo
我已经详细阐述了下面的第二点。这也是一种非常基本的方法。如果您有兴趣,可以搜索其他实现“动态字段”的方式(https://dev59.com/_k7Sa4cB1Zd3GeqP5rLk)。 - Cyril

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接