Axis2 機能拡張モジュールの作成方法 ~SOAP レスポンスにヘッダーを追加する~

Axis2 で、Web サービスを実装しました。メッセージの内容は、AXIOM (Axis2 の DOM ?) を使って生の XML で扱う方法を採用しました。そんな中、SOAP レスポンスにヘッダーを追加したくなり、その方法を調べたので、まとめました。

ど素人ゆえ、勘違いとか間違いがたくさんあると思います。おかしな点があったら、ご指摘いただけると嬉しいです。

今回作成したい Web サービスの内容

お客様サポートの問い合わせをリクエストとして受け取り、それに対する返事をレスポンスとする Web サービスを作成することにします。とはいえサービスの内容自体はどうでもよくて、今回の目標は、「SOAP レスポンスにヘッダーを追加し、「お問い合わせ番号」を設定する」こととします。

SOAP リクエスト

期待する SOAP レスポンス (ヘッダーに「お問い合わせ番号」を設定している)

axis2-create-module_qd9z60jz
ほんまに、ウマい!

SOAP ヘッダーの追加は、どこで行うの?

サービス クラスの実装は、次の様にしました。

サービス クラス

このように、 サービス メソッドの戻り値としては、 あくまで、レスポンスのボディ部分のみを返します。当然、このサービスを呼び出しても、ヘッダーは存在しません。

SOAP レスポンス (ヘッダーが無い…)

「じゃあ、ヘッダーを追加したいときは、どこでやるの?」ということになるのですが、結論としては「サービス クラスではできません。別途、『モジュール』を作成して下さい」ということのようです。

『モジュール』『フロー』『フェーズ』『ハンドラー』とは

というわけで、ここからモジュールを作成していく必要があるのですが、そもそも『モジュール』とは?また、モジュールを作成するにあたり『フロー』『フェーズ』『ハンドラー』という概念が出てくるので、先にこれらについてまとめておこうと思います。

  • Axis2 では、『モジュール』を作成することにより、独自の機能拡張を行うことができる。
  • SOAP レスポンスにヘッダーを追加するには、この『モジュール』を作成することが必要。
  • Axis2 の処理は一連の『フロー』で構成されている。また、各フローは一連の『フェーズ』で構成されている。作成したモジュールは、どのフローで実行するかを指定してやる必要がある。

■『フロー』とは

『フロー』は、Axis2 のエンジンが実行する処理の流れを、4 つの論理的な区分に分けたもののようです。4 つとは、「InFlow」「InFaultFlow」「OutFlow」「OutFaultFlow」です。

フロー 意味
InFlow  メッセージの入力を処理するフロー
InFaultFlow  メッセージの入力 (Fault 時) を処理するフロー
OutFlow  メッセージの出力を処理するフロー
OutFaultFlow  メッセージの出力 (Fault 時) を処理するフロー

■『フェーズ』とは

『フェーズ』とは、1 つのフローをさらに論理的に区切ったものです。つまり、1 つのフローの中に、フェーズが複数存在します。また、フローはあらかじめ Axis2 でによって 4 つに決まっていますが、フェーズは何個でも存在でき、自前のフェーズを新たに定義することもできます。

■『ハンドラー』とは

『ハンドラー』とは、フェーズに対してあらかじめ登録しておくものです。Axis2 のエンジンによって対象のフェーズが実行される時に、登録されているハンドラーの処理が呼び出されます。

■文章だとややこしいので、自分の理解を図にしてみました。(間違っていたら、すんません。)

axis2-create-module_hryd1j4m

モジュールを作成するために必要な作業

モジュールを作成するには、いろいろなファイルを作成または編集する必要があり、ちょっと大変です。具体的には、次の作業を行うことになります。

  1. モジュール クラスを実装する
  2. ハンドラー クラスを実装する
  3. フェーズを定義する (axis2.xml ファイルの編集) 任意
  4. モジュール定義を作成する (module.xml ファイルの作成)
  5. サービスにモジュールを割り当てる (services.xml ファイルの編集)

モジュール クラスを実装する

まず、Module インターフェイスを実装したクラスを作成します。このインターフェイスには 5 つのメソッドがあり、モジュールの初期化時や終了時の処理などを実装するようですが、今回は特に何もすることがないので、処理は空にしておきます。

モジュール クラス

ハンドラー クラスを実装する

次に、AbstractHandler クラスを継承したクラスを作成します。invoke メソッドをオーバーライドし、ここに実際に行いたい処理、つまり今回であれば、SOAP ヘッダーを追加する処理を実装します。

ハンドラー クラス

フェーズを定義する (axis2.xml ファイルの編集)

Axis2 の設定ファイル (axis2.xml ファイル) には、以下の通り、はじめから数種類のフェーズが定義されています。

設定ファイル (axis2.xml) 一部抜粋

これらの定義済みのフェーズにおいてモジュールを実行するのであれば、設定を編集する必要はありません。モジュールを実行するために専用のフェーズを追加するのであれば、定義済みフェーズと同じ記述方法で、フェーズを追加します。

これはあくまで私の予想ですが、定義済みフェーズ「OperationInPhase」「OperationOutPhase」「OperationInFaultPhase」「OperationOutFaultPhase」は、汎用的な目的に使用するために定義されているフェーズなのでは?と思っています (名前の感じからして、なんとなく)。というわけで、今回は定義済みの「OperationOutPhase」にて、モジュールを実行することにします。(設定ファイルは特に編集しません。)

モジュール定義を作成する (module.xml ファイルの作成)

次に、モジュールの定義を記述するファイルを作成します。ファイル名は「module.xml」とします。

モジュール定義ファイル (module.xml)

サービスにモジュールを割り当てる (services.xml ファイルの編集)

最後に、サービスとモジュールを関連付けます。サービス定義ファイル (services.xml) を次のように編集します。

サービス定義ファイル (services.xml)

ここまでやって、Web サービスを呼び出すと、やっと当初希望していた通りの、SOAP ヘッダーが付与されたレスポンスが出力されます。「ヘッダーを追加するだけなのに、なんて大変なの…。もっと楽な方法は無いのかしら。」と正直思いました。ただ、この手法を知っておけば、ヘッダーを追加するだけではなくて、いろいろな機能を追加できるし、作ったモジュールやハンドラーは再利用することもできて便利かもしれません。

でも…。やっぱりできればもっと楽にやりたいなぁ、というのが本音ですなぁ。もしヘッダーを追加する方法をご存じの方は、ぜひとも教えていただければ嬉しいです。

デプロイする時の話

上記の一連の作業を、私は開発環境 (Eclipse) 上で試していたので、クラスや設定ファイルを生で扱っていたのですが、実行環境にデプロイするときは、モジュール一式を『mar ファイル』にする必要があります。mar ファイルは、拡張子が「.mar」のファイルで、『jar ファイル』と同じように作ります。Axis2 のサービスを『aar ファイル』にするのと同じ考え方でしょう。

最終的なプロジェクトの構成内容

一連の作業を行った後の、最終的なプロジェクトの内容 (Eclipse のソリューション エクスプローラー) は、このようになりました。
axis2-create-module_nxkhhf5h

KPDN

KPDN has written 21 articles

プログラミングとゲームが好きな、しがないにゃんこ好きです。わんこも同じぐらい好きです。最近、物忘れどんどんが酷くなってきた。

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">