ファイヤープロジェクト
Beanのシリアライズとデシリアライズ(AXIS 1.2)
2005-10-08T16:00+09:00   matsu
SOAPにてJavaオブジェクトを送受信する場合は,XML文書とJavaオブジェクトを相互に変換する(シリアライズ,デシリアライズする)必要がある.今回はBeanのシリアライズ,デシリアライズの方法を調査してみた.
Javaプリミティブ型やString型をSOAPにて送受信する場合には,それらをXML電文に変換(シリアライズ)する方法や,逆にXML電文からJavaオブジェクトを生成する(デシリアライズ)方法を事前に決めておくことができる. 実際,今までのサンプルは,Javaプリミティブ型とString型の送受信であったので,
<helloReturn xsi:type="xsd:string">hello!!!</helloReturn>
といったように,既存の定義(ここでxsdはhttp://www.w3.org/2001/XMLSchema)を使用することによって,JavaのデータをXMLに落し込み,受信側ではその逆を行っていた. ここで,例えば以下のような独自のクラスHogeのオブジェクトを送受信するWebサービスを提供するとなった場合,このオブジェクトをどうXMLに落し込み,またオブジェクトに戻すかといったルールや実装が必要になる.
こうした仕組みを導入するために,AXISでは以下の作業が必要になる.
シリアライズ,デシリアライズ方法の合意
送信側と受信側で,送受信するデータに関して,そのシリアライズ,デシリアライズ方法を決めておかないと,双方のシステムでコミュニケーションできないので,決めておく.
シリアライザ,デシリアライザの実装
取り決めたシリアライズ,デシリアライズ方法にしたがって,それを行うコードを記述する. ただしBeanに関しては,axisにて提供されているを使用することができる(独自実装の必要がない).
  • org.apache.axis.encoding.ser.BeanSerializer
  • org.apache.axis.encoding.ser.BeanDeserializer
この場合,先の合意の内容も,上記クラスを使用するといったことと,該当BeanクラスのFQCNやXML電文上の名前空間を決める程度ですむ.
クライアントの実装
とりきめたシリアライザとデシリアライザを使用するよう,クライアントを実装する必要がある.
サーバへのシリアライザ,デシリアライザのデプロイ
とりきめたシリアライザとデシリアライザをサーバにデプロイする
本頁では,入門的な記述として,BeanSerializerとBeanDesirializerを使用するサンプルを作成した. このサンプルのWebサービスはSOAP RPCで先述のクラスHogeのオブジェクトを回答したり,引数に取る. 次節以降に合意やクライアントの実装やデプロイについて記述する.
実装する前に,送受信双方において以下の合意がなされているものとした(※).
HogeオブジェクトはJava Beanである.
HogeのFQCNはorg.fireproject.axissample.Hoge. シリアライズ,デシリアライズには
  • org.apache.axis.encoding.ser.BeanSerializer
  • org.apache.axis.encoding.ser.BeanDeserializer
を使用できるよう,各Hogeプロパティにはアクセサを定義する. 先述のHogeはこの条件を既に満たしている.
HogeオブジェクトのXML電文上での表記
名前空間"http://www.fireproject.jp/ns/axissample/hoge"の要素hogeにて記述する.
以上の合意のもと作成されたWebサービスを以下に示す.
Hogeオブジェクトをnewして返すgetNewHogeと,Hogeオブジェクトをパラメータにとり,更新して返すupdateHogeの二つのメソッドをSOAP RPCにて提供する.
※ 実際にはサービスのより上流の要件の摺合わせがあって,次に実装レベルでの摺合わせとなったり,それらがスパイラルしたりするかと思う.
クライアントコードを以下に示す.
クライアントでは,従来の設定に加えて,送受信データのシリアライザ,デシリアライザを指定する必要がある. その前に,シリアライザとデシリアライザを設定する対象のXML電文上でのQNameを作成する. この際にあらかじめ決めておいたHogeの名前空間,要素名を指定する.
QName qn = new QName("http://www.fireproject.jp/ns/axissample/hoge", "hoge");
次にシリアライザ,デシリアライザを指定する. これには以下を指定する必要がある.
  • Javaクラス
  • Javaクラスに対応するXML電文上での要素(QName)
  • シリアライザファクトリクラス
  • デシリアライザファクトリクラス
ここではシリアライザファクトリクラスとデシリアライザファクトリクラスには,axisにて提供されているBean用のものを指定する.
call.registerTypeMapping(Hoge.class,
                         qn,
                         BeanSerializerFactory.class,
                         BeanDeserializerFactory.class);
これでクライアントは,JavaクラスHogeのXML電文上での表記のマッピングと相互変換を行うことができるようになる. クライアント側での後の作業は今までと同様,エンドポイントの指定やメソッド,パラメータの指定である.
サーバ側でも,独自のオブジェクトとXML電文を相互変換できるよう,準備が必要である. ただし,その独自オブジェクトがBeanであり,axisで提供されているBeanSerializerとBeanDeserializerを使用できる場合には,デプロイ作業をする以外,従来のSOAP RPCと作業は変わらない. 以下にHogeFactoryのためのdeploy.wsddを示す.
要素serviceは今までどおりの記述内容である. 今回は新しい要素beanMappingが記述されている. これでJava BeanオブジェクトとXML電文上の記述とのマッピングを行う. まず,HogeのXML電文上でのQNameを指定するため,名前空間を定義する.
    xmlns:axissample="http://www.fireproject.jp/ns/axissample/hoge"
そしてその名前を使用してHogeのためのQNameを指定する.
    qname="axissample:hoge"
最後にそのHogeの言語(ここではjava)とFQCNを指定する.
    languageSpecificType="java:org.fireproject.axissample.Hoge"
以上で,axisはJava BeanであるHogeとXML電文上の要素hogeとのマッピングが分かるようになり,そのシリアライズとデシリアライズを自動的に行ってくれる. クライアント側では,若干のコーディングが必要であったが,サーバ側ではwsddの記述のみで,HogeFactory.jwsにシリアライズとデシリアライズのための記述が全く無い点に注意.
jwsなので,デプロイ後一度はjwsに要求して,コンパイルしてもらう必要がある.
$> java -jar axissample.jar http://soapserver/fireproject/HogeFactory.jws
org.fireproject.axissample.Hoge[updated = false; updateMessage = null; ]
org.fireproject.axissample.Hoge[updated = true; updateMessage = HogeFactory updated this hoge.; ]

$> java -jar axissample.jar http://soapserver/fireproject/services/Hoge 
org.fireproject.axissample.Hoge[updated = false; updateMessage = null; ]
org.fireproject.axissample.Hoge[updated = true; updateMessage = HogeFactory updated this hoge.; ]
サンプルでは二回SOAP RPC呼び出しを行う. 一回目はパラメータなしのgetNewHoge呼び出しで,Hogeオブジェクトを受け取る. 以下はその回答電文.
要素getNewHogeReturnからhrefで指定されるmultiRef(id="id0")にHogeオブジェクトの詳細が記述されている. そこにHogeオブジェクトのプロパティを名前に持つ子要素が並んでいる. updatedはhrefにて何故かさらに別のmultiRef(id="id1")に詳細記述を外出ししている... 何だかよくわからない. この辺の詳細は機会があれば調査したい. 最後に二回目のパラメータありのupdateHoge呼び出しの送信電文を記述しておく.
やはり何だかよく分からない.
matsu(C)
Since 2002
Mail to matsu