トップ 差分 一覧 ソース 検索 ヘルプ PDF RSS ログイン

Axis1.1:実践

[カテゴリ:アプリケーション]

Axis概要

  • AxisはApache Projectにて開発/メンテナンスされているWebサービス実行/開発環境
  • AxisのエンジンはTomcat上で稼動するServletプログラム
  • 本ページは全て「SOAP over HTTP」上での「SOAP-RPC」例である。

Axisパッケージに含まれるMyServiceサービスをテスト実行

Axisパッケージに含まれるMyServiceサービス
samples.userguide.example3.MyService
を使ってみる。

MyServiceサービスを実行してみる。

デプロイ(deploy)することで、Webサービスとして公開される。
公開されているWebサービスに対して、リクエストする。

↓デプロイ前にMyServiceサービスをリクエストしてみる。→NG

$ cd /usr/local/axis
$ java -classpath .:$AXIS_CLASSPATH samples.userguide.example3.Client abc
The AXIS engine could not find a target service to invoke!  targetService is  null

↓MyServiceサービスをデプロイする。

$ java -classpath .:$AXIS_CLASSPATH org.apache.axis.client.AdminClient samples/userguide/example3/deploy.wsdd
Processing file samples/userguide/example3/deploy.wsdd
<Admin>Done processing</Admin>

↓デプロイ後にMyServiceサービスをリクエストしてみる。→OK

$ java -classpath .:$AXIS_CLASSPATH samples.userguide.example3.Client abc
You typed : abc

↓MyServiceサービスをアンデプロイする。

$ java -classpath .:$AXIS_CLASSPATH org.apache.axis.client.AdminClient samples/userguide/example3/undeploy.wsdd
Processing file samples/userguide/example3/undeploy.wsdd
<Admin>Done processing</Admin>

↓アンデプロイ後にMyServiceサービスをリクエストしてみる。→NG

$ java -classpath .:$AXIS_CLASSPATH samples.userguide.example3.Client abc
The AXIS engine could not find a target service to invoke!  targetService is null

サービス側ソース(MyService.java)

/usr/local/axis/samples/userguide/example3/MyService.java

package samples.userguide.example3;

public class MyService
{
    public String serviceMethod(String arg)
    {
        return arg;
    }
}

クライアント側ソース(Client.java)

/usr/local/axis/samples/userguide/example3/Client.java

package samples.userguide.example3;

import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.encoding.XMLType;
import org.apache.axis.utils.Options;

import javax.xml.namespace.QName;
import javax.xml.rpc.ParameterMode;

public class Client
{
    public static void main(String [] args)
    {
        try {
            Options options = new Options(args);

            String endpointURL = options.getURL();
            String textToSend;

            args = options.getRemainingArgs();
            if ((args == null) || (args.length < 1)) {
                textToSend = "<nothing>";
            } else {
                textToSend = args[0];
            }

            Service  service = new Service();
            Call     call    = (Call) service.createCall();

            call.setTargetEndpointAddress( new java.net.URL(endpointURL) );
            call.setOperationName( new QName("MyService", "serviceMethod") );
            call.addParameter( "arg1", XMLType.XSD_STRING, ParameterMode.IN);
            call.setReturnType( org.apache.axis.encoding.XMLType.XSD_STRING );

            String ret = (String) call.invoke( new Object[] { textToSend } );

            System.out.println("You typed : " + ret);
        } catch (Exception e) {
            System.err.println(e.toString());
        }
    }
}

公開されているWebサービス・・・

デプロイされたサービスは、以下ファイルに登録される。
/usr/local/tomcat/webapps/axis/WEB-INF/server-config.wsdd

単純型を使ったサンプル実例

概要

サービス名:HelloService
メソッド名:String sayHello(String)

以下イメージで動作させる。

ans1 = HelloService.sayHello("鈴木")
→ans1:"こんにちは 鈴木さん あなたは、1番目の訪問者です。"

ans2 = HelloService.sayHello("佐藤")
→ans2:"こんにちは 佐藤さん あなたは、2番目の訪問者です。"

フォルダ・ファイル構成

/.../axis ・・・ サンプル用ルート
 +soaptest
  +HelloService.java ・・・・・・・HelloService本体
  +HelloLocalApp.java  ・・・・・・HelloServiceをローカル起動(テスト用)
  +HelloClientApp.java ・・・・・・HelloServiceをSOAP経由で利用するクライアント
  +deploy.wsdd ・・・・・・・・・・HelloServiceデプロイ用wsdd
  +deploy_scope_app.wsdd・・・・・・HelloServiceデプロイ用wsdd(ScopeがApplication版)
  +undeploy.wsdd・・・・・・・・・・HelloServiceアンデプロイ用

/usr/local/tomcat/webapps/axis/WEB-INF/classes
 +soaptest
  +HelloService.class・・・・・・・・デプロイの前にClassを配置しておく

なお、以下作業においてカレントディレクトリは/.../axisを想定します。

ソースコード

HelloService.java

package soaptest;

public class HelloService
{
  private int cntValue;

  public HelloService() {
    cntValue = 0;
  }

  public String sayHello(String name) {
    cntValue ++;
    return "こんにちは " + name + "さん あなたは、" + cntValue + "番目の訪問者です。";
  }

}

HelloLocalApp.java

package soaptest;

public class HelloLocalApp {
  public static void main(String args[]) {
    HelloService obj = new HelloService();
    String result;
    result = obj.sayHello(args[0]); System.out.println(result);
    result = obj.sayHello(args[1]); System.out.println(result);
  }
}

HelloClientApp.java

package soaptest;

import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.encoding.XMLType;
import org.apache.axis.utils.Options;

import javax.xml.namespace.QName;
import javax.xml.rpc.ParameterMode;

public class HelloClientApp
{
    public static void main(String [] args)
    {
        try {
            Options options = new Options(args);

            String textToSend1 = "null";
            String textToSend2 = "null";

            args = options.getRemainingArgs();
            if (args.length > 0) { textToSend1 = args[0]; }
            if (args.length > 1) { textToSend2 = args[1]; }


            // Webサービスのエンドポイント取得
            String endpointURL = options.getURL();
            if (args.length > 2) { endpointURL = args[2]; }

            // サービスとCallオブジェクトの取得
            Service  service = new Service();
            Call     call    = (Call) service.createCall();
            call.setTargetEndpointAddress( new java.net.URL(endpointURL) );

            // サービス・メソッド名、引数型、戻り値型 を指定
            call.setOperationName( new QName("soaptestHelloService", "sayHello") );
            call.addParameter( "arg1", XMLType.XSD_STRING, ParameterMode.IN);
            call.setReturnType( org.apache.axis.encoding.XMLType.XSD_STRING );

            // サービスを実際に呼び出し
            String ret1 = (String) call.invoke( new Object[] { textToSend1 } );
            System.out.println(ret1);
            String ret2 = (String) call.invoke( new Object[] { textToSend2 } );
            System.out.println(ret2);
        } catch (Exception e) {
            System.err.println(e.toString());
        }
    }
}

deploy.wsdd

<deployment xmlns="http://xml.apache.org/axis/wsdd/"
            xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">

 <service name="soaptestHelloService" provider="java:RPC">
  <parameter name="className" value="soaptest.HelloService"/>
  <parameter name="allowedMethods" value="*"/>
 </service>

</deployment>

deploy_scope_app.wsdd

ほぼ deploy.wsdd と同じ。
以下行を追加したのみ。

  <parameter name="scope" value="application"/>
<deployment xmlns="http://xml.apache.org/axis/wsdd/"
            xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">

 <service name="soaptestHelloService" provider="java:RPC">
  <parameter name="className" value="soaptest.HelloService"/>
  <parameter name="allowedMethods" value="*"/>
  <parameter name="scope" value="application"/>
 </service>

</deployment>

undeploy.wsdd

<undeployment xmlns="http://xml.apache.org/axis/wsdd/">
 <service name="HelloService"/>
</undeployment>

Axisへの登録まで

ソースコンパイルからAxis登録までを順に説明する。

「*.java」をコンパイル

$ javac -classpath .:$AXIS_CLASSPATH soaptest/*.java

↓以下が生成される。
soaptest/HelloServer.class
soaptest/HelloLocalApp.class
soaptest/HelloClientApp.class

動作確認 - HelloServiceをローカル起動

単に HelloLocalApp から HelloService.sayHello() をCallするだけ。
(通常のローカルアプリ)

$ java soaptest/HelloLocalApp 鈴木 佐藤
こんにちは 鈴木さん あなたは、1番目の訪問者です。
こんにちは 佐藤さん あなたは、2番目の訪問者です。

Webサービスとして公開するJavaClass(HelloService.class)をAxis配下にコピー

$ su
Password:
# mkdir /usr/local/tomcat/webapps/axis/WEB-INF/classes/soaptest
# cp soaptest/HelloService.class /usr/local/tomcat/webapps/axis/WEB-INF/classes/soaptest
# exit
exit
$

HelloServiceをデプロイ

$ java -classpath .:$AXIS_CLASSPATH org.apache.axis.client.AdminClient soaptest/deploy.wsdd
Processing file soaptest/deploy.wsdd
<Admin>Done processing</Admin>

動作確認 - AxisにHelloServiceが登録されているか確認

http://localhost:8080/axis/servlet/AxisServlet

※なぜか空白ページが表示されたりしてしまった。。。
何が起きているのかよくわからないが・・・
・Tomcatの再起動
・/usr/local/tomcat/webapps/axis/WEB-INF/server-config.wsdd を削除
などやっていると直った?

※上記を踏まえTomcatの設定を変更して、リロードとした。
/usr/local/tomcat/conf/server.xml

<!-- Axis Context -->
<Context path="/axis" docBase="axis" debug="0" reloadable="true"/>

動作確認 - SOAP経由でHelloServiceを呼び出し(スコープ「request」)

$ java -classpath .:$AXIS_CLASSPATH soaptest.HelloClientApp 鈴木 佐藤
こんにちは 鈴木さん あなたは、1番目の訪問者です。
こんにちは 佐藤さん あなたは、1番目の訪問者です。

※上記では、どちらも「1番目の訪問者」となっている。
 これは、呼び出しの都度新規にインスタンスが生成される為である。
※デフォルトスコープは「request/1度のSOAP要求ごとにインスタンス化」となっている。

動作確認 - スコープを「application」に変更した場合

デプロイ時のwsddで、スコープを「application/1つのWebサービス実行環境(アプリケーション・サーバ)ごとにインスタンス化」にした場合

java -classpath .:$AXIS_CLASSPATH org.apache.axis.client.AdminClient soaptest/deploy_scope_app.wsdd
Processing file soaptest/deploy_scope_app.wsdd
<Admin>Done processing</Admin>
java -classpath .:$AXIS_CLASSPATH soaptest.HelloClientApp 鈴木 佐藤
こんにちは 鈴木さん あなたは、1番目の訪問者です。
こんにちは 佐藤さん あなたは、2番目の訪問者です。
java -classpath .:$AXIS_CLASSPATH soaptest.HelloClientApp 鈴木 佐藤
こんにちは 鈴木さん あなたは、3番目の訪問者です。
こんにちは 佐藤さん あなたは、4番目の訪問者です。

動作確認 - スコープを「session」に変更した場合

「session/Webサービス・クライアントごとにインスタンス化」とすることで
以下の動作結果となる。

java -classpath .:$AXIS_CLASSPATH soaptest.HelloClientApp 鈴木 佐藤
こんにちは 鈴木さん あなたは、1番目の訪問者です。
こんにちは 佐藤さん あなたは、2番目の訪問者です。
java -classpath .:$AXIS_CLASSPATH soaptest.HelloClientApp 鈴木 佐藤
こんにちは 鈴木さん あなたは、1番目の訪問者です。
こんにちは 佐藤さん あなたは、2番目の訪問者です。

「session」を有効とするには、デプロイ(wsdd)の他、クライアントアプリに以下の細工が必要となる。

HelloClientApp.java

 :
Service  service = new Service();
service.setMaintainSession(true); ←これを追加
Call     call    = (Call) service.createCall();
 :

複合型を使ったサンプル実例

・・・
・WSDL2Javaを使って、WSDL文書からスタブコード(.java)を生成

Webサービスで例外が発生した場合

SOAPフォルトとなる。
このときAxisはWebサービスの例外を捕らえたときのトレースログを
以下に出力している。
/usr/local/tomcat/logs/catalina.out

リンク

@IT - Java Solution - 連載記事 「パソコンで試してわかるWebサービス
http://www.atmarkit.co.jp/fjava/index/index_wbsrvic.html

最終更新時間:2005年02月23日 16時53分05秒