web-dev-qa-db-ja.com

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/>

私の本はどこにありますか? :)

18
yegor256

マーシャリングされる要素は、パブリックであるか、XMLElement注釈を持っている必要があります。 ArrayListクラスとクラスBooksは、これらのルールのいずれにも一致しません。簿価を提供する方法を定義し、それに注釈を付ける必要があります。

コードで、「セルフゲッター」メソッドを追加してBooksクラスのみを変更します。

@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>

(わかりやすくするために改行を追加しました)

16
Tomas Narros

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>
2
musiKk

@Blaiseと@musiKkが指摘しているように、単に本のリストを本に入れて、本を真のルート要素にする方がよいでしょう。 ArrayListの拡張は、私自身のコードでは受け入れ可能な手順とは見なしません。

0
Half_Duplex