JAXBのガイド
1. 概要
これは、JAXB(Java Architecture for XML Binding)の入門チュートリアルです。
最初に、JavaオブジェクトをXMLに、またはその逆に変換する方法を示します。
次に、JAXB-2 Mavenプラグインを使用して、XMLスキーマからJavaクラスを生成することに焦点を当てます。
2. JAXBの概要
JAXBは、JavaオブジェクトをXMLにマーシャリング(書き込み)し、XMLをオブジェクトにアンマーシャリング(読み取り)するための高速で便利な方法を提供します。 これは、Javaアノテーションを使用してXML要素と属性をJavaフィールドとプロパティにマップするバインディングフレームワークをサポートします。
JAXB-2 Mavenプラグインは、その作業のほとんどを、JDKが提供する2つのツールXJCおよびSchemagenのいずれかに委任します。
3. JAXBアノテーション
JAXBは、Javaアノテーションを使用して、生成されたクラスに追加情報を追加します。 このようなアノテーションを既存のJavaクラスに追加すると、JAXBランタイム用にそれらが準備されます。
まず、マーシャリングとアンマーシャリングを説明するための単純なJavaオブジェクトを作成しましょう。
@XmlRootElement(name = "book")
@XmlType(propOrder = { "id", "name", "date" })
public class Book {
private Long id;
private String name;
private String author;
private Date date;
@XmlAttribute
public void setId(Long id) {
this.id = id;
}
@XmlElement(name = "title")
public void setName(String name) {
this.name = name;
}
@XmlTransient
public void setAuthor(String author) {
this.author = author;
}
// constructor, getters and setters
}
上記のクラスには、次のアノテーションが含まれています。
- @XmlRootElement:T ルートXML要素の名前はクラス名から派生します。また、name属性を使用してXMLのルート要素の名前を指定することもできます。
- @XmlType :フィールドがXMLファイルに書き込まれる順序を定義します
- @XmlElement :使用される実際のXML要素名を定義します
- @XmlAttribute:idフィールドが要素ではなく属性としてマップされることを定義します
- @XmlTransient:XMLに含めたくないフィールドに注釈を付けます
JAXBアノテーションの詳細については、このリンクを確認してください。
4.4。 マーシャリング–JavaオブジェクトのXMLへの変換
マーシャリングにより、クライアントアプリケーションはJAXBから派生したJavaオブジェクトツリーをXMLデータに変換できます。 デフォルトでは、MarshallerはXMLデータを生成するときにUTF-8エンコーディングを使用します。 次に、JavaオブジェクトからXMLファイルを生成します。
JAXBContext を使用して簡単なプログラムを作成しましょう。これは、JAXBバインディングフレームワーク操作を実装するために必要なXML/Javaバインディング情報を管理するための抽象化を提供します。
public void marshal() throws JAXBException, IOException {
Book book = new Book();
book.setId(1L);
book.setName("Book1");
book.setAuthor("Author1");
book.setDate(new Date());
JAXBContext context = JAXBContext.newInstance(Book.class);
Marshaller mar= context.createMarshaller();
mar.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
mar.marshal(book, new File("./book.xml"));
}
javax.xml.bind.JAXBContext クラスは、JAXBAPIへのクライアントのエントリポイントを提供します。 デフォルトでは、JAXBはXMLドキュメントをフォーマットしません。 これにより、スペースが節約され、空白が誤って重要であると解釈されるのを防ぐことができます。
JAXBで出力をフォーマットするには、MarshallerでMarshaller.JAXB_FORMATTED_OUTPUTプロパティをtrueに設定するだけです。 marshalメソッドは、オブジェクトと出力ファイルを使用して、生成されたXMLをパラメーターとして保管します。
上記のコードを実行すると、 book.xml の結果をチェックして、JavaオブジェクトがXMLデータに正常に変換されたことを確認できます。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<book id="1">
<title>Book1</title>
<date>2016-11-12T11:25:12.227+07:00</date>
</book>
5. アンマーシャリング–XMLをJavaオブジェクトに変換する
アンマーシャリングにより、クライアントアプリケーションはXMLデータをJAXBから派生したJavaオブジェクトに変換できます。
JAXB Unmarshaller を使用して、book.xmlをJavaオブジェクトにアンマーシャリングしてみましょう。
public Book unmarshall() throws JAXBException, IOException {
JAXBContext context = JAXBContext.newInstance(Book.class);
return (Book) context.createUnmarshaller()
.unmarshal(new FileReader("./book.xml"));
}
上記のコードを実行すると、コンソール出力をチェックして、XMLデータがJavaオブジェクトに正常に変換されたことを確認できます。
Book [id=1, name=Book1, author=null, date=Sat Nov 12 11:38:18 ICT 2016]
6.6。 複雑なデータ型
JAXBで直接利用できない可能性のある複雑なデータ型を処理する場合、特定の型を管理する方法をJAXBに示すアダプターを作成できます。
これを行うには、JAXBの XmlAdapter を使用して、マップできないクラスをJAXBが処理できるものに変換するカスタムコードを定義します。 @XmlJavaTypeAdapter アノテーションは、カスタムマーシャリング用にXmlAdapterクラスを拡張するアダプターを使用します。
マーシャリング時に日付形式を指定するアダプターを作成しましょう。
public class DateAdapter extends XmlAdapter<String, Date> {
private static final ThreadLocal<DateFormat> dateFormat
= new ThreadLocal<DateFormat>() {
@Override
protected DateFormat initialValue() {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
}
};
@Override
public Date unmarshal(String v) throws Exception {
return dateFormat.get().parse(v);
}
@Override
public String marshal(Date v) throws Exception {
return dateFormat.get().format(v);
}
}
日付形式yyyy-MM-ddHH:mm:ss を使用して、マーシャリング時にDateをStringに変換し、ThreadLocalを作成します。 DateFormatスレッドセーフ。
DateAdapterをBookに適用してみましょう。
@XmlRootElement(name = "book")
@XmlType(propOrder = { "id", "name", "date" })
public class Book {
private Long id;
private String name;
private String author;
private Date date;
@XmlAttribute
public void setId(Long id) {
this.id = id;
}
@XmlTransient
public void setAuthor(String author) {
this.author = author;
}
@XmlElement(name = "title")
public void setName(String name) {
this.name = name;
}
@XmlJavaTypeAdapter(DateAdapter.class)
public void setDate(Date date) {
this.date = date;
}
}
上記のコードを実行すると、 book.xml の結果をチェックして、新しい日付形式yyyy-MM-ddHHを使用してJavaオブジェクトをXMLに正常に変換したことを確認できます。 mm:ss :
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<book id="1">
<title>Book1</title>
<date>2016-11-10 23:44:18</date>final
</book>
7. JAXB-2Mavenプラグイン
このプラグインは、Java API for XML Binding(JAXB)バージョン2+を使用して、XMLスキーマ(およびオプションでバインディングファイル)からJavaクラスを生成するか、注釈付きのJavaクラスからXMLスキーマを作成します。
Webサービスを構築するには、 ContractLastとContractFirstの2つの基本的なアプローチがあることに注意してください。 これらのアプローチの詳細については、このリンクを確認してください。
7.1. XSDからのJavaクラスの生成
JAXB-2 Mavenプラグインは、XSD(XMLスキーマ定義)からJavaクラスを生成するJAXBバインディングコンパイラツールであるJDK提供のツールXJCを使用します。
単純なuser.xsdファイルを作成し、JAXB-2 Mavenプラグインを使用して、このXSDスキーマからJavaクラスを生成してみましょう。
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="/jaxb/gen"
xmlns:userns="/jaxb/gen"
elementFormDefault="qualified">
<element name="userRequest" type="userns:UserRequest"></element>
<element name="userResponse" type="userns:UserResponse"></element>
<complexType name="UserRequest">
<sequence>
<element name="id" type="int" />
<element name="name" type="string" />
</sequence>
</complexType>
<complexType name="UserResponse">
<sequence>
<element name="id" type="int" />
<element name="name" type="string" />
<element name="gender" type="string" />
<element name="created" type="dateTime" />
</sequence>
</complexType>
</schema>
JAXB-2Mavenプラグインを構成しましょう。
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<id>xjc</id>
<goals>
<goal>xjc</goal>
</goals>
</execution>
</executions>
<configuration>
<xjbSources>
<xjbSource>src/main/resources/global.xjb</xjbSource>
</xjbSources>
<sources>
<source>src/main/resources/user.xsd</source>
</sources>
<outputDirectory>${basedir}/src/main/java</outputDirectory>
<clearOutputDir>false</clearOutputDir>
</configuration>
</plugin>
デフォルトでは、このプラグインはXSDファイルを src / main /xsdに配置します。 pom.xml のこのプラグインの構成セクションを適宜変更することで、XSDルックアップを構成できます。
また、デフォルトでは、これらのJavaクラスは target /generated-resources /jaxbフォルダーに生成されます。 プラグイン構成にoutputDirectory要素を追加することにより、出力ディレクトリを変更できます。 このディレクトリ内のファイルが消去されないように、値がfalseのclearOutputDir要素を追加することもできます。
さらに、デフォルトのバインディングルールをオーバーライドするグローバルJAXBバインディングを構成できます。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<jaxb:bindings version="2.0" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
jaxb:extensionBindingPrefixes="xjc">
<jaxb:globalBindings>
<xjc:simple />
<xjc:serializable uid="-1" />
<jaxb:javaType name="java.util.Calendar" xmlType="xs:dateTime"
parse="javax.xml.bind.DatatypeConverter.parseDateTime"
print="javax.xml.bind.DatatypeConverter.printDateTime" />
</jaxb:globalBindings>
</jaxb:bindings>
上記のglobal.xjbは、dateTimeタイプをjava.util.Calendarタイプにオーバーライドします。
プロジェクトをビルドすると、 src / main /javaフォルダーとパッケージcom.baeldung.jaxb.genにクラスファイルが生成されます。
7.2. JavaからのXSDスキーマの生成
同じプラグインは、JDKが提供するツールSchemagenを使用します。 これは、JavaクラスからXSDスキーマを生成できるJAXBバインディングコンパイラツールです。 JavaクラスがXSDスキーマ候補に適格であるためには、クラスに@XmlTypeアノテーションが付けられている必要があります。
前の例のJavaクラスファイルを再利用して、プラグインを構成します。
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<id>schemagen</id>
<goals>
<goal>schemagen</goal>
</goals>
</execution>
</executions>
<configuration>
<sources>
<source>src/main/java/com/baeldung/jaxb/gen</source>
</sources>
<outputDirectory>src/main/resources</outputDirectory>
<clearOutputDir>false</clearOutputDir>
<transformSchemas>
<transformSchema>
<uri>/jaxb/gen</uri>
<toPrefix>user</toPrefix>
<toFile>user-gen.xsd</toFile>
</transformSchema>
</transformSchemas>
</configuration>
</plugin>
デフォルトでは、JAXBは src / main / java の下のすべてのフォルダーを再帰的にスキャンして、注釈付きのJAXBクラスを探します。 プラグイン構成にsource要素を追加することにより、JAXB注釈付きクラスに別のsourceフォルダーを指定できます。
XSDスキーマの命名を担当するポストプロセッサであるtransformSchemasを登録することもできます。 これは、namespaceをJavaクラスの@XmlTypeの名前空間と照合することで機能します。
プロジェクトをビルドすると、user-gen.xsdファイルがsrc/ main /resourcesディレクトリに生成されます。
8. 結論
この記事では、JAXBの概要について説明しました。 詳細については、JAXBホームページを参照してください。
この記事のソースコードはGitHubにあります。