JAXBに関して
AngularJSを使うとRestを作ることが多くなるので、
サーバーサイドのJava側の方も書きたいと思います。
今回は、JavaのJAXBに関して、書きたいと思います。
それで、RestやSOAPで、結果をXMLやJSONで戻す時にJAXBを使うですが、
なにをしてくれるかと言うとですね。
XMLとかJSONなどをJavaクラスへマッピングしてくれるものになります。
例えば、こんなJSONを戻したいと思ったら
{'category' : [{'key' : '1000', 'value' : 'AAAAA'}, {'key' : '2000', 'value' : 'BBBBB'}]}
JAXBのクラスは、下記のような記述になります。
@XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "", propOrder = {"category"}) @XmlRootElement(name = "categoryResouce") public class CategoryResouce { protected List<CategoryList.Category> category; public List<CategoryList.Category> getCategory() { if (category == null) { category = new ArrayList<CategoryList.Category>(); } return this.category; } @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "", propOrder = {"key","value"}) public static class Category { protected String key; protected String value; public String getKey() { return key; } public void setKey(String value) { this.key = value; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } } }
Categoryクラスにkey,valueのプロパティを定義します。
それで、@XmlAccessorType(XmlAccessType.FIELD)の定義と、
@XmlTypeに、key,valueと言う名前を定義すると、JSONの下記の部分がマッピングされます。
{'key' : '', 'value' : ''}
また、このCategoryクラスを保持するクラスが必要になります。
やり方は、2種類あり、
親クラスを作成して、Categoryクラスをネストさせ、
親クラスのプロパティにCategoryクラスのインスタンスを保持できるようにするか、
別クラスを作って、プロパティにCategoryクラスのインスタンスを保持できるようにする方法があります。
ネストクラスの方がらくなので、ネストクラスがおすすめです。
複数存在する場合は、Categoryクラスのリストを保持するように作ります。
外のクラスは、Categoryクラスのリストを保持するようにして、
@XmlTypeを使って、categoryと言う名前を定義します。
JSONのJSONの下記の部分がマッピングされます。
{'category' : []}
これで、JSONやXMLをJavaクラスへマッピング可能になります。
このJAXBのクラスを今の様に一から書く方法とXMLファイルから自動生成する方法があります。
XMLファイルから生成する方法ですが、
自分の環境の場合、Apache Mavenを利用しているので、
まずは、Mavenのpom.xmlに下記の定義を追加します。
<dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-xjc</artifactId> <version>2.2.7</version> </dependency> <dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-impl</artifactId> <version>2.2.7</version> </dependency> <dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-osgi</artifactId> <version>2.2.7</version> </dependency>
これで、自動的に必要なライブラリがダウンロードされてくると思います。
それと、XMLファイルを配置するディレクトリとして、configディレクトリを作成します。
次に下のMavenコマンドで、build.xml、maven-build.xml、maven-build.propertiesを生成します。
mvn ant:ant
生成できたら、その中のbuild.xmlを下記のように編集します。
<taskdef name="xjc" classname="com.sun.tools.xjc.XJCTask"> <classpath refid="build.classpath"/> </taskdef> <target name="xjc"> <xjc destdir="src"> <schema dir="config" includes="*.xsd"/> </xjc> </target>
次にXMLファイルを作成します。
作成したら、先ほど作成したconfigディレクトリにファイルを置きます。
今回の場合は、下の様な定義なります。
<schema targetNamespace="http://chronos/system/gyao/service/resource_1" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://chronos/system/gyao/service/resource_1" xmlns:dv="http://chronos/system/gyao/service/resource_1" elementFormDefault="qualified"> <element name="categoryResouce"> <complexType> <sequence> <element name="category" maxOccurs="unbounded"> <complexType> <sequence> <element name="key" type="string"/> <element name="value" type="string"/> </sequence> </complexType> </element> </sequence> </complexType> </element> </schema>
これで、準備完了なので、antのxjcタスクを実行すると、JAXB対応のJavaクラスが生成されます。
あと、JAXB対応のRESTやSOAPなどのフレームワークで利用すれば、
簡単にJSONやXMLのリクエストやレスポンスなどをなにもしないで、Javaクラスへ自動マッピングすることが
できると思います。
ちなみに、自分は、Restサービスの場合、Jerseyで、JAXBを使ってます。
なので、次回は、JerseyでのRestサービスに関して、書こうと思います。