2013-05-11 30 views
3

我想根据请求和用户选择性地序列化字段。如何告诉JAXB在运行时序列化哪些字段?

例如,管理员用户将被提供一个带有一些额外字段的XML。而普通用户会得到没有这些字段的XML。其次,目前我使用@XmlIDREF来防止引用对象或集合的不必要的扩展。

但有时候用户可能需要这些细节。对被引用的对象进行第二次请求是不可取的。我想让用户告诉服务器XYZ属性应该扩展(即包括完整的对象,而不仅仅是其参考)

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

尽可能地,我不想创建一个XSD。请注意,请求参数是动态的。序列化的字段在运行时决定。所以我不能使用硬编码的东西 - 比如@Transient@XmlIDREF注释。

回答

2

注:我是EclipseLink JAXB (MOXy)铅和JAXB (JSR-222)专家小组的成员。

在EclipseLink 2.5中(在此处获取:http://www.eclipse.org/eclipselink/downloads/milestones.php),我们向MOXy JAXB添加了一个名为Object Graphs的新功能。对象图允许以编程方式或通过元数据选择您想要编组/解组的属性的子集。以下是创建对象图以获取Customer,AddressPhoneNumber模型的数据子集的示例。

// 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); 

更多信息

+0

谢谢,这很好。效果很好。但是,我在编辑子图中的ID字段时遇到了一些问题。我有一个类A的对象列表(包装在一个JaxbList中)。类A的每个对象都有一个B类对象的列表。我通过传递给JaxbList.class来创建对象图。从那我为B创建一个子图.A按预期序列化,但是子图的ID字段没有被序列化。如果我通过将B保存为主图(而不是子图)来尝试编组,则按预期序列化ID字段。任何想法可能是错的?我试着注释掉XmlID注释。它仍然发生。 – Dojo 2013-05-14 13:43:14

1

我也不会试图挖掘XSD。这里我的建议是:

1-缺省情况下,JAXB不应该序列化空字段。 所以你可以简单地取消字段,你不想序列化。

为了更干净一点,我建议您取消业务对象的副本。只是为了确保你不会在应用程序中产生副作用。


2-您也可以使用地图和存储<String, Object>使您的字段动态。 这将让你完全控制你的领域生命周期。

编辑:关键将是您的变量名称和值将您的对象引用。如果你的值应该是一个原始的,那么你可以将你的值自动装箱到相关的对象容器中。 JAXB将从地图序列化所有现有的值。

如果您必须在多个类中共享密钥定义,我建议您将(key,value)的创建/销毁封装到另一个类中。


3-如果要强制执行一组特定的属性,它们可以是空或不是在同一时间,如果下面的抽象为您的应用意义。 您还可以定义具有不同属性的子类的子集。父类将具有必须具有的属性。

好运

+0

感谢。我正在考虑做类似于第1点的事情,但它不是很整齐。说,对象A引用B.我显然不会在引用B时使用XmlIDREF,因为它会阻止B被扩展。但是现在,当我不想扩展B时,除了保存ID的字段外,我必须将B的所有字段设置为null。不是很漂亮,但可以完成,迄今看起来像最好的选择。你能否详细说明第2点? – Dojo 2013-05-11 10:48:22

+0

我已经详细阐述了第2点,就在它下面。这也是一个非常基本的方法。如果你有兴趣,你可以搜索其他方式来实现“动态字段”(http://stackoverflow.com/questions/3127189/java-classes-with-dynamic-fields) – Cyril 2013-05-11 11:07:17

相关问题