j3259の日記: Java で Web Service
Java で Web Service を作ろうとしている。仕事を一日休んだ割にはあんまり進んでいない。
しかも Tomcat も Axis2 も全然理解してない。
開発環境ごと職場と自宅で持ち運べるように取り合えず Windows XP の vm (vmware) をコピーしてくる。
使い慣れてるなら各種 Linux でも問題無し。
- Cygwin をインストール(Windows を使ってる場合)
- jdk 1.5.0 をインストール
- tomcat, axis2, mytomcat をインストール(人からもらったものを展開して適当な所に置いただけ)
- jdk 1.5.0 フォルダ名(E:\Java\jdk1.5.0_11)を JAVA_HOME という環境変数に入れる。
- E:\tomcat は CATALINA_HOME、E:\axis2 は AXIS2_HOME、F:\dev\mytomcat は CATALINA_BASE という環境変数に入れる
- apache-ant をインストールして、パスを通す
- eclipse をインストール
- $CATALINA_BASE/conf/server.xml でポート番号を決める
- $CATALINA_BASE/conf/tomcat-users.xml でユーザネームとパスワードを決める
- $CATALINA_BASE/webapps/axis2/WEB-INF/conf/axis2.xml で Axis2 のアドミンユーザ名とパスワードを決める
- Cygwin にて
$ $CATALINA_HOME/bin/startup.sh
で Tomcat を立ち上げる。
ブラウザで http://localhost:8080/ (ポート8080の場合)を開くと Tomcat が出てくるはず。
Tomcat Manager に入り、/axis2、Services を開く。
準備は以上。
----
サービスクラスを書く。
パッケージ名.service.FooService.java に
package bla.bla.service;
public class BankOfFooService {
public int deposit(String a_accountNumber, int a_amount) {
return 0;
}
public int withdraw(String a_accountNumber, int a_amount) {
return 0;
}
public int query(String a_accountNumber) {
return 0;
}
}
みたいな感じで普通に Java クラスを書く。
「普通の Java クラス」というのは整数を返すのに普通の int を使うなど特別な型を使ってないこと。POJO(plain old Java oject)という。
services.xml を書く。
Sample にあるものを適当に直して src/META-INF に置く。
build.xml を書く。
Sample にあるものを適当に直して build.xml を書く。
<property environment="env" />
<property name="axis2.home" value="${env.AXIS2_HOME}" />
<property name="catalina.base" value="${env.CATALINA_BASE}" />
<property name="deployment.path" value="${catalina.base}/webapps/axis2/WEB-INF" />
とする事で環境変数も使える。
ビルドして、
<copy file="${dest.dir}/${service.name}.aar" tofile="${deployment.path}/services/${service.name}.aar" overwrite="true" />
すると、勝手にデプロイしてくれるらしい。
http://localhost:8080/axis2/services/listServices を開くと、BankOfFooService がデプロイされている。
途中でミスった場合は axis2 ごと reload する必要があるかも。(もっとマトモな方法があるかも)
http://localhost:8080/axis2/services/BankOfFooService?wsdl で何と wsdl が生成されている。
.NET Framework 並みのことができますよ、ということか。
とりあえず、ここで Apache Axis2/Java Version 1.2 Documentation Index 一応出しておく。
message receiver っていうのが何かイマイチ分からないんだけど、org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver と org.apache.axis2.rpc.receivers.RPCMessageReceiver が POJO (int とかを使った普通の Java オブジェクトのこと)を xml のやり取りに変換してくれてるってことみたい。最終的には SOAP もしくは HTTP(XML-RPC?)で話してる。
Apache Axis2 Tools の Code Generator Wizard - Eclipse Plug-in というのを試してみる。zip を解凍して、Axis2_Codegen_Wizard_1.2.0 フォルダごと、eclipse の plugin フォルダに入れて、eclipse を再起動するだけ。
自動生成みたいなことをする前に、subclipse を入れて、今あるものをコミットしておく。
(実際には、フォルダを別名に変えて、TortoiseSVN 使ってプロジェクトを作って、コミットして、Subclipse からアクセスしてチェックアウトしたのを元のプロジェクト名で保存するという手続きを取る)
せっかくサーバ側を自動生成したわけだから、クライアント側も自動生成して真ん中にwire(LAN もしくは WAN の事)がある事は忘れてしまいたい。
Eclipse にて、New > Other > Axis2 Wizards > Axis2 Code Generator
- Generate Java source code from a WSDL file (WSDL から Java コードを生成)
- http://localhost:8080/axis2/services/BankOfFooService?wsdl
- custom を選んでパッケージ名を bla.bla.client にする。
- プロジェクトを選ぶ。ルートを選ぶこと。親切に src と入れたら、src の中に src を作るので注意。
ここで気付いたのが、僕が使ってる Axis が最新版じゃないらしいということ。
仕方がないので Cygwin より、
$ $AXIS2_HOME/bin/wsdl2java.bat -url http://localhost:8080/axis2/services/BankOfFooService?wsdl -p bla.bla.client -d abd -s
として古いコードを生成する。
最新版の Axis2 だともうちょっと使えるコードが生成されるかもしれないが、Axis 1.1.1 が吐き出したコードはそのままじゃ使いづらい。メソッドの引数にオブジェクトを生成してて、deposit(String a_accountNumber, int a_amount) の場合は a_accountNumber と a_amount をそれぞれオブジェクトにセットする必要がある。戻り値も同様。エラー処理とかがあるとしてもせっかく synchronous(同期; リクエストの度にレスポンスが返ってくるまで待つ事)指定してる意味が無い。asynchronous(非同期; リクエストは投げっぱなし。レスポンスはコールバックやイベントで受け取る)の場合はリクエストとレスポンスでオブジェクトを分ける必要があるんだけど。仕方がないから、自分でラッパーを書く。
public int deposit(String a_accountNumber, int a_amount) throws RemoteException {
BankOfFooServiceStub.Deposit param = new BankOfFooServiceStub.Deposit();
param.setParam0(a_accountNumber);
param.setParam1(a_amount);
BankOfFooServiceStub.DepositResponse response = m_stub.Deposit(param);
return response.get_return();
}
public int withdraw(String a_accountNumber, int a_amount) throws RemoteException {
BankOfFooServiceStub.Withdraw param = new BankOfFooServiceStub.Withdraw();
param.setParam0(a_accountNumber);
param.setParam1(a_amount);
BankOfFooServiceStub.WithdrawResponse response = m_stub.Withdraw(param);
return response.get_return();
}
public int query(String a_accountNumber) throws RemoteException {
BankOfFooServiceStub.Query param = new BankOfFooServiceStub.Query();
param.setParam0(a_accountNumber);
BankOfFooServiceStub.QueryResponse response = m_stub.Query(param);
return response.get_return();
}
Java で Web Service More ログイン