Почему мой 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<Book> {
  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);

Вот что я вижу:

<?xml version="1.0"?>
<books/>

Где мои книги?:)

Ответы

Ответ 1

Элементы, подлежащие сортировке, должны быть общедоступными или иметь аномалию XMLElement. Класс ArrayList и ваши классы Книги не соответствуют ни одному из этих правил. Вы должны определить метод, предлагающий значения книги, и анонимность.

В вашем коде, изменяя только ваш класс "Книги", добавляя метод "self getter":

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

  @XmlElement(name = "book")
  public List<Book> getBooks() {
    return this;
  }
}

когда вы запустите свой код маршаллинга, вы получите:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<books><book><title>The Sign of the Four</title></book></books>

(Я добавил разрыв строки для ясности)

Ответ 2

Я не думаю, что вы можете легко настроить List как есть. Рассмотрите возможность использования другого класса для переноса списка. Следующие работы:

@XmlType
class Book {
    public String title;

    public Book() {
    }

    public Book(String t) {
        this.title = t;
    }
}

@XmlType
class Books extends ArrayList<Book> {
    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);

он производит этот результат:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<books><book><title>The Sign of the Four</title></book></books>

Ответ 3

Как отмечали @Blaise и @musiKk, было бы лучше просто иметь Список книг в Книгах и позволить Книгам быть истинным корневым элементом. Я бы не рассматривал расширение ArrayList приемлемой процедуры в моем собственном коде.