JAX-RS(Jersey)でのソースを自動生成させる方法に関して
システムのマスターを外部システムへ公開する為、
JAVAでRESTサービスを構築して対応するお仕事をしています。
RESTサービスのJAVAのフレームワークに関して、少し調査し、
今回は、JDK1.6とGlassFishV2の組み合わせで、
JAXBとSpringとのマッチングも問題なさそうな、JAX-RSの実装の1つのJerseyにしました。
レスポンスは、XML形式で戻すので、JAXBで、ある程度自動的に生成する方向で、できるだけ、コードを書かない方法を探し中です。
XMLSchemaを定義して、WADLファイルを公開するとある程度、JAXBのXJCタスクが必要なクラスは、自動生成してくれます。
JAXBでJavaクラスにメッセージをマッピングすることは、簡単になるのですが、複数のスキーマからメッセージを構築すると、
XML形式のレスポンスを見ると、名前空間が付与されたメッセージになります。
JAVAクライアントの場合は、基本的に問題ないと思われますが、PHPやRubyのクライアントが
XML解釈が結構大変かも?
SOAPの場合もパースするのが大変だったので、今回も大変そうな気がします。
そもそもXMLSchemaで厳密にメッセージを定義して、WADLファイルで、公開すべきなのか?など疑問がある。
ただ個人的には、XMLSchemaやWADLがあると要素の出現順番や出現回数などが理解し易く、
メッセージ構造を簡単に把握できるので、定義されていた方が楽かなと思っています。
XMLSchemaが理解できない人などは、敷居が高いかも、SOAPの時も何回も良くわからないと言われた。
結局、XMLSchemaベースの仕様書と実際のメッセージパターンを定義したものを作成して、何とかわかってもらえるように対応したりしていました。
多分、今回も同じ対応するような気がします。
ちなみに、WADLファイルに関しては、賛否両論的な部分もあるので、今後、どうなるかわからない。
もっとゆるい感じで、RESTサービスを利用したい人には、XMLSchemaやWADLファイルで、メッセージやオペレーションを定義されるとなんか大変そうと思われるかもしれません。
それで、実装方法ですが、基本的には、自動生成したソースをベースに実装します。
自動生成の方法は、wadl2Javaを利用し生成します。
下記のサイトからダウンロードすることができます。
https://wadl.dev.java.net/
準備として、メッセージ定義をしたXMLSchemaをまず作成します。
まず名前空間を定義します。
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://developer.co.jp/system/dev/schemas/Message_1" elementFormDefault="qualified"> </schema>
次に、レスポンスメッセージを定義します。
レスポンスは、文字列を返すだけのレスポンスにしておきます。
定義は、下記の定義とします。
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://developer.co.jp/system/dev/schemas/Message_1" elementFormDefault="qualified"> <element name="messageResponse"> <complexType> <sequence> <element name="message"> <simpleType> <restriction base="string"> <minLength value="1"/> <maxLength value="1000"/> </restriction> </simpleType> </element> </sequence> </complexType> </element> </schema>
それと、例外系のメッセージも定義しておきます。
例外は、アプリケーション系とシステム系の例外時のメッセージを定義します。
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://developer.co.jp/system/dev/schemas/Message_1" elementFormDefault="qualified"> ・ ・ ・ <element name="applicationFault"> <complexType> <sequence> <element name="faultMessage"> <simpleType> <restriction base="string"> <minLength value="1"/> <maxLength value="1000"/> </restriction> </simpleType> </element> </sequence> </complexType> </element> <element name="systemFault"> <complexType> <sequence> <element name="faultMessage"> <simpleType> <restriction base="string"> <minLength value="1"/> <maxLength value="1000"/> </restriction> </simpleType> </element> </sequence> </complexType> </element> </schema>
XMLSchemaの定義は、完了で、WADLファイルを定義します。
WADLは、下記の様な定義になると思います。
<?xml version="1.0" encoding="UTF-8" ?> <application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://research.sun.com/wadl/2006/10 wadl.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://research.sun.com/wadl/2006/10" xmlns:message="http://developer.co.jp/system/dev/schemas/Message_1"> <grammars> <include href="http://localhost:7777/system/dev/schemas/Message_1_0.xsd"/> </grammars> <resources base="http://localhost:7777/MessageResource_1_0/MessageResource/service"> <resource path="/getMessageByMessageId"> <method name="GET"> <request> <param name="messageId" type="xsd:string" style="query" required="true"/> </request> <response> <representation mediaType="application/xml" element="message:messageResponse"/> <fault status="400" mediaType="application/xml" element="message:applicationFault"/> <fault status="500" mediaType="application/xml" element="message:systemFault"/> </response> </method> </resource> </resources> </application>
最後にbuild.xml(antです。)を定義します。
<?xml version="1.0" encoding="UTF-8"?> <project name="MessageResource"> <property name="project.name" value="MessageResource"/> <property name="version" value="1_0"/> <property name="revision" value="1"/> <property name="build.lib" value="WebContent/WEB-INF/lib/"/> <property name="build.src" value="src"/> <property name="build.gen" value="gen"/> <property name="build.bin" value="bin"/> <property name="build.dist" value="dist"/> <property name="build.wadl" value="WebContent/WEB-INF/wadl/MessageResource_1_0.wadl"/> <property name="build.package" value="jp.co.developer.system.dev.wadl.messageresource_1"/> <path id="classpath"> <fileset dir="${build.lib}"> <include name="*.jar"/> </fileset> </path> <taskdef name="wjc" classname="org.jvnet.ws.wadl2java.WJCTask"> <classpath refid="classpath"/> </taskdef> <target name="generate"> <wjc description="${build.wadl}" package="${build.package}" autoSchemaPackage="true" target="${build.gen}"/> <echo message="test"/> </target> </project>
これで、準備完了です。
antで、generateを実行すれば、WADLファイルからソースが生成されます。