JAXB を使ってオブジェクトを marshal する際に要素名を指定する方法

公開日: : 最終更新日:2014/01/26 JAXB ,

JAXB を使ってオブジェクトを marshal する際に要素名を変更したい場合があるかと思います。
アノテーションを付与するだけで希望の名称で出力できますので、その方法をメモしておきます。

icatch-jaxb-marshal2

目次

  1. アノテーションで指定しない場合の marshal
  2. アノテーションで指定した場合の marshal
  3. まとめ
  4. 検証プログラムを Github に登録しました
  5. その他の JAXB に関する記事

1. アノテーションで指定しない場合の marshal

例えば、次の Book クラスがあったとして。

public class Book {
    
    /**
     * タイトル。
     */
    private String title;
    
    /**
     * 出版社。
     */
    private String publisher;

    /**
     * ページ数。
     */
    private int numberOfPages;

    /**
     * デフォルトコンストラクタが無いと marshal 時に javax.xml.bind.DataBindingException が発生してしまう。
     */
    public Book() {}

    public Book(String title, String publisher, int numberOfPages) {
        this.title = title;
        this.publisher = publisher;
        this.numberOfPages = numberOfPages;
    }

    public String getTitle() {
        return title;
    }

    /**
     * setter を定義しないと marshal することはできるが、このフィールドの値が出力されない。
     * 
     * @param title
     */
    public void setTitle(String title) {
        this.title = title;
    }

    public String getPublisher() {
        return publisher;
    }

    /**
     * setter を定義しないと marshal することはできるが、このフィールドの値が出力されない。
     * 
     * @param publisher
     */
    public void setPublisher(String publisher) {
        this.publisher = publisher;
    }

    public int getNumberOfPages() {
        return numberOfPages;
    }

    /**
     * setter を定義しないと marshal することはできるが、このフィールドの値が出力されない。
     * 
     * @param numberOfPages
     */
    public void setNumberOfPages(int numberOfPages) {
        this.numberOfPages = numberOfPages;
    }
}

例えば、次のテストケースがあったとして。

public class BookTest {
    
    private Book sut;

    @Before
    public void setUp() throws Exception {
        sut = new Book("本のタイトル", "本の出版社", 208);
    }

    @Test
    public void JAXBでmarshalする() throws Exception {
        JAXB.marshal(sut, System.out);
    }
}

このテストケースを実行すると、標準出力に次のように出力されます。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<book>
    <numberOfPages>208</numberOfPages>
    <publisher>本の出版社</publisher>
    
</book>

フィールド名と同じ名称で要素が出力されます。
上記の場合、Lower CamelCase なので要素名も Lower CamelCase で出力されます。

2. アノテーションで指定した場合の marshal

フィールド numberOfPages の名称を snake_case で出力する場合は @XmlElement アノテーションを使います。

上記のフィールド numberOfPages の要素名を “number_of_pages” と出力するしたい場合は、 numberOfPages の getter メソッドに @XmlElement アノテーションを付与します。

具体的なコードは次の通りです。

public class BookWithXmlElementAnnotation {

    /**
     * タイトル。
     */
    private String title;
    
    /**
     * 出版社。
     */
    private String publisher;

    /**
     * ページ数。
     */
    private int numberOfPages;

    /**
     * デフォルトコンストラクタが無いと marshal 時に javax.xml.bind.DataBindingException が発生してしまう。
     */
    public BookWithXmlElementAnnotation() {}

    public BookWithXmlElementAnnotation(String title, String publisher, int numberOfPages) {
        this.title = title;
        this.publisher = publisher;
        this.numberOfPages = numberOfPages;
    }

    public String getTitle() {
        return title;
    }

    /**
     * setter を定義しないと marshal することはできるが、このフィールドの値が出力されない。
     * 
     * @param title
     */
    public void setTitle(String title) {
        this.title = title;
    }

    public String getPublisher() {
        return publisher;
    }

    /**
     * setter を定義しないと marshal することはできるが、このフィールドの値が出力されない。
     * 
     * @param publisher
     */
    public void setPublisher(String publisher) {
        this.publisher = publisher;
    }

    /**
     * <code>@XmlElement</code> で要素名を指定する。
     * 
     * @return
     */
    @XmlElement(name = "number_of_pages")
    public int getNumberOfPages() {
        return numberOfPages;
    }

    /**
     * setter を定義しないと marshal することはできるが、このフィールドの値が出力されない。
     * 
     * @param numberOfPages
     */
    public void setNumberOfPages(int numberOfPages) {
        this.numberOfPages = numberOfPages;
    }
}

このクラスに対して marshal を実行すると次の内容が標準出力に出力されます。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<bookWithXmlElementAnnotation>
    <number_of_pages>208</number_of_pages>
    <publisher>本の出版社</publisher>
    
</bookWithXmlElementAnnotation>

フィールド numberOfPages が指定した内容で出力されています。

3. まとめ

オブジェクトを XML に marshal したり、逆に unmarshal するのって、ブラウザで実行される JavaScript に対してだったり、または、外部サービスと連携するときだと思います。

今は XML よりも JSON を使う機会が多いと思いますが、まだ需要はあります。

JAXB は Java の標準 API に組み込まれているためライブラリを追加しなくても利用できます。機能を全部抑えるのは大変ですが、どんなことができるのか簡単にさらっておくといいかもしれないです。

4. 検証プログラムを Github に登録しました

今回の記事で使用したサンプルプログラムを Github に登録しました。

jaxb-sample/src/main/java/net/tomoyamkung/jaxb/sample02 パッケージに登録されているプログラムになります。
パッケージに登録されているプログラムになります。

5. その他の JAXB に関する記事

JAXB に関する記事は次の通りです。
気になる記事があったらぜひチェックしてみてください!

Googleアドセンス用(PC)

  • このエントリーをはてなブックマークに追加
  • follow us in feedly

関連記事

medium_8179595608

リストに格納されているオブジェクトを marshal する場合に付与すると便利な @XmlElementWrapper アノテーション

JAXB を使ってリストに格納されているオブジェクトを marshal する際に付与すると便利な @

記事を読む

icatch-marshal

JAXB を使ってオブジェクトを marshal するために忘れてはいけない2つのこと

JAXB を使ってオブジェクトを marshal するために必要な2つの忘れてはいけないことをメモし

記事を読む

Googleアドセンス用(PC)

Message

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です


四 + = 13

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Googleアドセンス用(PC)

icatch-jersey_multi_pathparams
Jerseyの@PathParamはスラッシュの間に複数指定できる

http://hoge-api/user/{id}.{format}

icatch-vagrant_box_customize
VagrantのBoxファイルをカスタマイズして独自のBoxファイルを作成する

配布されている Vagrant の Box ファイルを使って検証環境を

icatch-2015-006-1
バリデーションチェックにJava8のOptionalを使ってスマートに書く(自分比)

Web アプリのバリデーションチェックにアノテーションを使うことが増え

icatch-2015-005-1
ユニットテストの偏りを防ぐ命名規則の付け方

ユニットテスト名に以下の命名規則を付けるようにして二ヶ月ぐらい経った。

icatch-2015-004-1
Vagrantで起動したCentOS上のOctopressをホストOSから確認する設定

タイトルの通りだが、Vagrant を使って起動した CentOS に

→もっと見る

PAGE TOP ↑