为什么我的ArrayList没有用JAXB编组?

这是用例:

@XmlRootElement public class Book { public String title; public Book(String t) { this.title = t; } } @XmlRootElement @XmlSeeAlso({Book.class}) public class Books extends ArrayList { public Books() { this.add(new Book("The Sign of the Four")); } } 

然后,我正在做:

 JAXBContext ctx = JAXBContext.newInstance(Books.class); Marshaller msh = ctx.createMarshaller(); msh.marshal(new Books(), System.out); 

这就是我所看到的:

   

我的书在哪里? 🙂

要编组的元素必须是公共的,或者具有XMLElement anotation。 ArrayList类和您的类Books与这些规则中的任何一个都不匹配。 您必须定义一个方法来提供Book值,并对其进行分析。

在您的代码上,只更改您的Books类添加“自我getter”方法:

 @XmlRootElement @XmlSeeAlso({Book.class}) public class Books extends ArrayList { public Books() { this.add(new Book("The Sign of the Four")); } @XmlElement(name = "book") public List getBooks() { return this; } } 

当你运行你的编组代码时,你会得到:

  The Sign of the Four 

(为了清晰起见,我添加了换行符)

我认为你不能轻易地按原样编组List 。 考虑使用另一个类来包装列表。以下工作:

 @XmlType class Book { public String title; public Book() { } public Book(String t) { this.title = t; } } @XmlType class Books extends ArrayList { public Books() { this.add(new Book("The Sign of the Four")); } } @XmlRootElement(name = "books") class Wrapper { public Books book = new Books(); } 

使用如下:

 JAXBContext ctx = JAXBContext.newInstance(Wrapper.class); Marshaller msh = ctx.createMarshaller(); msh.marshal(new Wrapper(), System.out); 

它会产生这样的结果:

  The Sign of the Four 

正如@Blaise和@musiKk指出的那样,最好只有一本Book of Book书籍,并允许Books成为真正的根元素。 我不认为在我自己的代码中扩展ArrayList是一个可接受的过程。