我使用@XmlID和@XmlIDREF標記來引用另一個對象。即使使用繼承的類,它在Java 6中也能正常工作。我創建的示例代碼如下所示。 基類中使用標籤:XmlID/XmlIDREF和最新JAXB版本(Java 7)中的繼承
@XmlRootElement
@XmlAccessorType(FIELD)
public class Module {
Module() {}
@XmlIDREF
private Module other;
@XmlID
private String id;
public Module(String id, Module other) {
this.id = id;
this.other = other;
}
}
繼承類:
集裝箱這些類:
@XmlRootElement
public class Script {
Script() {}
public Script(Collection<Module> modules) {
this.modules = modules;
}
@XmlElementWrapper
@XmlElementRef
Collection<Module> modules = new ArrayList<Module>();
}
運行此示例代碼:
public class JaxbTest {
private Script createScript() {
Module m1 = new Module("Module1", null);
Module m2 = new TheModule("Module2", m1, "featured module");
Module m3 = new Module("Module3", m2);
return new Script(Arrays.asList(m1, m2, m3));
}
private String marshal(Script script) throws Exception {
JAXBContext context = JAXBContext.newInstance(Module.class, Script.class, TheModule.class);
Writer writer = new StringWriter();
context.createMarshaller().marshal(script, writer);
return writer.toString();
}
private void runTest() throws Exception {
Script script = createScript();
System.out.println(marshal(script));
}
public static void main(String[] args) throws Exception {
new JaxbTest().runTest();
}
}
我收到在Java 6中的XML:
<script>
<modules>
<module>
<id>Module1</id>
</module>
<theModule>
<other>Module1</other>
<id>Module2</id>
<feature>featured module</feature>
</theModule>
<module>
<other>Module2</other>
<id>Module3</id>
</module>
</modules>
</script>
請注意,對m2(TheModule實例)的引用已按預期序列化。 但當相同的代碼的Java 7(JAXB 2.2.4-1)下運行,我收到:
<script>
<modules>
<module>
<id>Module1</id>
</module>
<theModule>
<other>Module1</other>
<id>Module2</id>
<feature>featured module</feature>
</theModule>
<module>
<other xsi:type="theModule" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<other>Module1</other>
<id>Module2</id>
<feature>featured module</feature>
</other>
<id>Module3</id>
</module>
</modules>
</script>
所以,你可以看到,最新的JAXB @XmlIDREF爲繼承模塊不能正常工作!
謝謝您的回答。我有些疑惑。 JAXBContext.newInstance(Class ...)的Javadoc聲明調用者必須列出頂級類。 「新的上下文將識別指定的所有類,但它也將識別任何直接/間接引用的類**從指定的類靜態**(sic!)。被引用的類的子類和@XmlTransient引用的類未註冊JAXBContext中。「 如果我們將此聲明康斯坦丁的例子,子類TheModule不會被自動發現。 \ –
@AndyMalakov看起來你是對的。當我回答這個問題時,我不記得是否已經閱讀過'newInstance'的文檔,但我記得我已經嘗試了一些代碼,並且我寫的內容似乎已經被檢查出來。由於OP沒有以任何方式迴應我的回答,所以我完全忘記了這一點。其實我可以看到我錯誤地解釋了實際的問題/問題,所以我的答案完全沒有了。我會更新我的答案以反映這一點。感謝您的輸入! –