Tôi đang sử dụng thẻ @XmlID và @XmlIDREF để tham chiếu một đối tượng từ một đối tượng khác. Nó hoạt động tốt trong Java 6 ngay cả với các lớp kế thừa. Mã ví dụ mà tôi đã tạo trông như thế này. class Base thẻ sử dụng:XmlID/XmlIDREF và kế thừa trong phiên bản JAXB mới nhất (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;
}
}
thừa kế lớp:
container cho các lớp này:
@XmlRootElement
public class Script {
Script() {}
public Script(Collection<Module> modules) {
this.modules = modules;
}
@XmlElementWrapper
@XmlElementRef
Collection<Module> modules = new ArrayList<Module>();
}
Khi chạy mã ví dụ này:
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();
}
}
tôi nhận được XML, trong Java 6:
<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>
Lưu ý rằng tham chiếu đến m2 (Ví dụ TheModule) được đăng theo mong đợi. Nhưng khi cùng mã đang chạy dưới Java 7 (JAXB 2.2.4-1) Tôi nhận:
<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>
Vì vậy, bạn có thể thấy rằng trên mới nhất JAXB @XmlIDREF cho module thừa hưởng không hoạt động!
Cảm ơn bạn đã trả lời của bạn. Tôi có một số nghi ngờ. Javadoc cho JAXBContext.newInstance (Class ...) nói rằng người gọi phải liệt kê các lớp cấp cao nhất. "bối cảnh mới sẽ nhận ra tất cả các lớp được chỉ định, nhưng nó cũng sẽ nhận ra bất kỳ lớp nào được tham chiếu trực tiếp/gián tiếp ** tĩnh ** (sic!) từ các lớp được chỉ định. Các lớp con của các lớp được tham chiếu cũng như các lớp tham chiếu @XmlTransient không được đăng ký với JAXBContext. ". Nếu chúng tôi áp dụng tuyên bố này vào ví dụ của Konstantin, lớp con cháu TheModule sẽ không được tự động phát hiện. \ –
@AndyMalakov Có vẻ như bạn đã đúng. Tôi không nhớ chính xác nếu tôi đã đọc tài liệu cho 'newInstance' trở lại sau đó khi tôi trả lời câu hỏi, nhưng tôi nhớ rằng tôi đã thử một số mã và những gì tôi đã viết dường như để kiểm tra. Vì OP không trả lời câu trả lời của tôi bằng bất cứ cách nào tôi đã quên hoàn toàn điều này. Trên thực tế tôi có thể thấy rằng tôi đã hiểu sai câu hỏi/vấn đề thực sự để câu trả lời của tôi hoàn toàn tắt. Tôi sẽ cập nhật câu trả lời của tôi để phản ánh điều này. Cảm ơn các đầu vào! –