2009-11-10 47 views
2

我正在使用JAXB來快速生成XML。我有一個代表樹形結構的類:有什麼辦法來限制JAXB中對象圖的編組深度?

@XmlRootElement(name = "element") 
public class Element { 

    // [...] 

    @XmlElementWrapper(name="childs") 
    @XmlElementRef 
    public List<Element> getChilds() { /*...*/ } 
} 

我想限制子集合被編組的深度。因此,例如,我想寫出我送給Marshaller的元素的直接孩子,但省略他們的孩子。

有沒有一個標準的JAXB方式來做到這一點,或者可能是一個回調我可以使用禁用動態的財產編組?

回答

1

您可以嘗試使用XmlJavaTypeAdapter註釋和您的實現XmlAdapter接口。

+0

我已經想到了,但無法弄清楚如何從適配器內部觸發JAXB對孩子的編組。沒有通過XmlAdapter接口訪問Marshaller,所以看起來我的選擇是:1)安裝一個新的,可以成爲一個大的性能命中或2)訪問當前的Marshaller - 例如使用一個自定義的ThreadLocal上下文類 - 我猜是不安全的(或者甚至可能),因爲這意味着重用Marshaller而另一個對象仍在處理中。 – FRotthowe 2009-11-10 21:00:13

+0

您可以使用一個Marshailer池並重新使用它們。無論如何,一次只能使用2個,因爲你真的只需要2個等級。 – 2009-11-10 21:53:19

+0

我會嘗試按照你的建議使用一個marshallers池。這不像「乾淨」的解決方案,但至少不需要對模型類進行更改。 – FRotthowe 2009-11-18 07:41:26

1

如果你知道你不會使用你的數據結構編組後,也可以輕鬆地做它的一個副本,我會定義編組(http://java.sun.com/javase/6/docs/api/javax/xml/bind/Marshaller.html#marshalEventCallback)回調函數:

boolean beforeMarshal(Marshaller); 
在你的元素類

。您可以使用此事件回調來跟蹤編組人員已達到的深度。當它達到極限深度時,只需將註釋的子屬性清空即可。默認情況下,JAXB在遇到null屬性時不會生成元素,因此編組器將在此處停止。

如果您想在編組後重新使用您的結構,您需要將不想序列化的孩子移動到未註釋的屬性中,然後在編組完成後將它們移回主要屬性,以玩遊戲:

void afterMmarshal(Marshaller); 

這種模式增添了幾分設計味道,因爲你有一個神奇的簽名是從來沒有從自己的代碼稱爲未標註的方法,但它確實工作。

+0

不幸的是,編組後我需要數據結構。實際上,這些對象是hibernate-mapped的:對它們的所有更改都可能被刷新到數據庫,因此直接修改它們似乎有點太冒險。 – FRotthowe 2009-11-18 07:38:38

相關問題