本ドキュメントはS2Axis2 について記述しています。
S2Axis2Examplesは、S2Axis2の基本的な機能を一通り使用したサンプルです。インストールについてはセットアップを参照してください。
ソースはサーバ側とクライアント側に分かれており、クライアント側はJUnit (S2Unit)
のテストケースとして作成されています。それぞれ、以下のソースフォルダにあります。
- サーバ側
src/main フォルダのorg.seasar.axis.examples
パッケージ
- クライアント側
src/test フォルダのorg.seasar.axis.examples
パッケージ
クライアント側では、リモート呼び出しの設定を、以下のdiconファイルで共通化しています。
dicon(クライアント側)
s2axis2-client.dicon
<components>
<component name="ioRemoting"
class="org.seasar.remoting.common.interceptor.RemotingInterceptor">
<property name="connector">ioConnector</property>
</component>
<component name="ioConnector"
class="org.seasar.remoting.axis2.connector.AxisInOutConnector">
<property name="baseURL">baseURL</property>
</component>
<component name="oneWayRemoting"
class="org.seasar.remoting.common.interceptor.RemotingInterceptor">
<property name="connector">oneWayConnector</property>
</component>
<component name="oneWayConnector"
class="org.seasar.remoting.axis2.connector.AxisOnewayConnector">
<property name="baseURL">baseURL</property>
</component>
<component class="org.apache.axis2.description.AxisService" autoBinding="none"/>
<component name="baseURL" class="java.net.URL" autoBinding="none">
<arg>"http://localhost:8080/s2axis2-examples/services/"</arg>
</component>
</components>
POJOのクラスをWebサービスとして公開することが可能です。
現在のバージョンでは、「同期型要求応答形式(Request/Response)」「一方向形式(Oneway)」をサポートしています。
一方向形式では、戻り値なし(void)でなければなりません。
サービスとして公開するクラス
src/main/java/org/seasar/remoting/axis2/examples/ex01/Echo.java
src/main/java/org/seasar/remoting/axis2/examples/ex01/EchoImpl.java
public interface Echo {
String echo(int id, String message);
}
public class EchoImpl implements Echo {
public String echo(int id, String message) {
return "[id = " + id + "] " + message;
}
}
dicon(サービス側)
src/main/resources/org/seasar/remoting/axis2/examples/ex01/deploy.dicon
<component name="Echo" class="org.seasar.remoting.axis2.examples.ex01.EchoImpl">
<meta name="axis-service"/>
</component>
dicon(クライアント側)
src/test/resources/org/seasar/remoting/axis2/examples/ex01/EchoTest.dicon
<include path="s2-axis-client.dicon"/>
<component class="org.seasar.remoting.axis2.examples.ex01.Echo">
<aspect>ioRemoting</aspect>
</component>
サービスとして公開するクラス
src/main/java/org/seasar/remoting/axis2/examples/ex01/Ping.java
src/main/java/org/seasar/remoting/axis2/examples/ex01/PingImpl.java
public interface Ping {
void ping(String message);
}
public class PingImpl implements Ping {
public void ping(String message) {
System.out.println(message);
}
}
dicon(サービス側)
src/main/resources/org/seasar/remoting/axis2/examples/ex01/deploy.dicon
<component name="Ping" class="org.seasar.remoting.axis2.examples.ex01.PingImpl">
<meta name="axis-service"/>
</component>
dicon(クライアント側)
src/test/resources/org/seasar/remoting/axis2/examples/ex01/PingTest.dicon
<include path="s2-axis-client.dicon"/>
<component class="org.seasar.remoting.axis2.examples.ex01.Ping">
<aspect>oneWayRemoting</aspect>
</component>
実装クラスを公開すると、不要なメソッドまで公開されてる場合があります(インタフェースを実装していない場合や複数のインタフェースを実装している場合など)。実装クラスHelloImpl は二つのインタフェースを実装していますが、MessageSettableのメソッドsetMessage(String) はWebサービスとして公開しないものとします。
このような場合には、公開するJavaインタフェースを指定します(実装したインタフェースが一つだけの場合や、実装した複数のインタフェースのメソッドを全て公開する場合には明示的に指定する必要はありません)。
dicon(サービス側)
src/main/resources/org/seasar/remoting/axis2/examples/ex02/deploy.dicon
<component name="Hello" class="org.seasar.remoting.axis2.examples.ex02.impl.HelloImpl">
<meta name="axis-service">
<component class="org.seasar.remoting.axis2.ServiceDef">
<property name="serviceType">
@org.seasar.remoting.axis2.examples.ex02.Hello@class
</property>
</component>
</meta>
<property name="message">"Hello"</property>
</component>
このサンプルでは、サービスは引数および戻り値の型としてJavaBeansを使用しています。プリミティブ型(およびそのラッパクラス型)を使用している場合は、特に何も指定しなくても動作します。
サービスとして公開するクラス
src/main/java/org/seasar/remoting/axis2/examples/ex03/BeanEcho.java
src/main/java/org/seasar/remoting/axis2/examples/ex03/impl/BeanEchoImpl.java
public interface BeanEcho {
EchoDto echo(EchoDto echoDto);
}
public class BeanEchoImpl implements BeanEcho {
public BeanEchoImpl() {}
public EchoDto echo(EchoDto echoDto) {
return echoDto;
}
}
public class EchoDto {
private String strParam = "";
private short shortParam = 1;
private int intParam = 2;
private long longParam = 3L;
private float floatParam = 1.0f;
private double doubleParam = 1.1;
private boolean boolParam = true;
// setter/getter
}
Axis2は、スコープを指定して、サービスのインスタンスを管理することができます。
S2Axis2では、S2コンテナがインスタンスを管理します。サービスをSessionスコープとして利用する場合には、以下のように指定します。
dicon(サービス側)
src/main/resources/org/seasar/remoting/axis2/examples/ex04/deploy.dicon
<components>
<component name="Counter"
class="org.seasar.remoting.axis2.examples.ex04.impl.CounterImpl"
instance="session">
<meta name="axis-service"/>
</component>
</components>
S2コンテナとAxis2におけるスコープの関連は、リファレンスを参照してください。
Axis2で利用するservices.xmlを指定して、サービスをデプロイします。
dicon(サービス側)
src/main/resources/org/seasar/remoting/axis2/examples/ex06/deploy.dicon
<components>
<meta name="axis-deploy">
"org/seasar/remoting/axis2/examples/ex05/services.xml"
</meta>
</components>
services.xml(Axis2のサービス定義ファイル)
src/main/resources/org/seasar/remoting/axis2/examples/ex05/services.xml
<service name="EchoBasedXml" scope="application">
<description>Echo Service.</description>
<messageReceivers>
<messageReceiver mep="http://www.w3.org/ns/wsdl/in-out"
class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
<messageReceiver mep="http://www.w3.org/ns/wsdl/in-only"
class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/>
</messageReceivers>
<parameter name="ServiceClass" locked="false">
org.seasar.remoting.axis2.examples.ex01.EchoImpl
</parameter>
<operation name="echo">
<actionMapping>urn:echo</actionMapping>
</operation>
</service>
ここでは、「コンポーネントをWebサービスとして公開する」で利用したEchoと同じサービスを定義していますが、クライアントの処理は、変更する必要はありません。
また、services.xmlを指定してデプロイしたサービスのインスタンス管理に、S2およびS2Axis2は関与しません。
services.xmlで指定したサービスのインスタンスは、S2コンテナからは取得できない(他のコンポーネントにインジェクションできない)ことに注意してください。
エンドポイントのURLを変更したい場合など、独自のWSDLファイルを指定してサービスをデプロイすることが可能です。
独自のWSDLファイルを適用するにはServiceDefを利用します。
独自のWSDLファイルを適用するには、まず、利用するWSDLファイルをクラスパス直下のMETA-INFディレクトリ配下に配置します。
WSDLのファイル名は、適用するサービス名に一致するようにします。
例)WEB-INF/classes/META-INF/EchoFormCustomWSDL.wsdl
WSDLを配置したら、以下のように、公開するサービスのdicon定義ファイルでServiceDefにパラメータを指定してください。
dicon(サービス側)
src/main/resources/org/seasar/remoting/axis2/examples/ex06/deploy.dicon
<component name="EchoFormCustomWSDL"
class="org.seasar.remoting.axis2.examples.ex01.EchoImpl">
<meta name="axis-service">
<component class="org.seasar.remoting.axis2.ServiceDef">
<initMethod name="addParameter">
<arg>"useOriginalwsdl"</arg>
<arg>"true"</arg>
</initMethod>
<initMethod name="addParameter">
<arg>"modifyUserWSDLPortAddress"</arg>
<arg>"false"</arg>
</initMethod>
</component>
</meta>
</component>
ServiceDef#addParameterメソッドで、「useOriginalwsdl」を「true」と指定することで、独自のWSDLが適用されます。
「modifyUserWSDLPortAddress」は、エンドポイントのURLを変更したい場合に指定してください。デフォルトは「true」ですが、
「false」を指定すると、WSDLで指定した値がそのまま利用されるようになります。
サービスをデプロイ後、ブラウザで以下のようにURLを指定すると、WSDLを確認することができます。
http://localhost:8080/s2axis2-examples/services/EchoFormCustomWSDL?wsdl
処理に応じて接続先を変更したい場合など、クライアントの処理でオプションパラメータを指定することが可能です。
変更するにはS2AxisClientContextクラスを利用します。
dicon(サービス側)
public class EchoClient {
private Echo service;
public EchoClient(Echo echo) {
this.service = echo;
}
public void execute() {
int id = 1;
String msg = "echo message";
String result;
// diconに設定されているURLで接続
S2AxisClientContext.setEndpointURL(null);
result = service.echo(id, msg);
System.out.println(result);
// このクラスで指定したURLで接続
S2AxisClientContext.setEndpointURL("http://localhost:8081/Echo");
result = service.echo(id, msg);
System.out.println(result);
}
public static void main(String[] args) {
SingletonS2ContainerFactory.setConfigPath("EchoTest.dicon");
SingletonS2ContainerFactory.init();
S2Container container = SingletonS2ContainerFactory.getContainer();
Echo echo = (Echo)container.getComponent(Echo.class);
EchoClient client = new EchoClient(echo);
client.execute();
}
}
S2Axis2で、Yahoo!のWebサービス用APIを利用してみます。Yahoo!のWebサービスに関する情報は、Yahoo!デベロッパーネットワークから得ることができます。
Yahoo!のWebサービスは、HTTP REST(Representational State
Transfer)によってアクセスすることが可能です。
本サンプルでは、Web検索のAPIを利用します。サービスはYahoo!のWebサービスとなるため、S2Axis2のクライアントの機能のみ使用します。
YahooSearchDto.java(リクエストパラメータを保持するクラス)
まず、ウェブ検索WebサービスのAPIにしたがって、リクエストパラメータを保持するDTOクラスを作成します。
ここでは、必須パラメータである、appid および query のみ指定しています。
public class YahooSearchDto {
private String appid; // アプリケーションID
private String query; // 検索クエリー
// setter/getter
}
YahooSearch.java(サービス呼び出しのインタフェース)
次に、サービスを呼び出すためのインタフェースを作成します。インタフェースのみを定義すれば、サービスを呼び出すことが可能です。
S2Axis2では、メソッドの名前に合わせてRESTの通信方式(Axis2 1.0
では、GET/POSTのみがサポートされています)を特定するため、メソッドの名前の付け方に注意してください。
- getXxx
- GET としてサービスを呼び出します。
- postXXX
- POST としてサービスを呼び出します。
public interface YahooSearch {
String postSearch(YahooSearchDto dto);
String getSearchResult(YahooSearchDto dto);
}
YahooSearchTest.dicon
コネクタにはorg.seasar.remoting.axis2.connector.RESTConnectorを指定し、接続先のURLには、ウェブ検索WebサービスのリクエストURLを指定してください。
上で作成したYahooSearchインタフェースに、RESTConnectorを設定したRemotingInterceptorをアスペクトとして指定します。
<component name="remoting" class="org.seasar.remoting.common.interceptor.RemotingInterceptor"/>
<component name="connector" class="org.seasar.remoting.axis2.connector.RESTConnector">
<property name="baseURL">
new java.net.URL("http://api.search.yahoo.co.jp/WebSearchService/V1/webSearch")
</property>
</component>
<component class="org.seasar.remoting.axis2.examples.rest.YahooSearch">
<aspect>remoting</aspect>
</component>
以上で、サービスを呼び出す準備が整いました。
クライアント
ウェブ検索Webサービスを呼び出します。ここでは、S2TestCaseとして作成しています。
public class YahooSearchTest extends S2TestCase {
public void setUp() {
include("YahooSearchTest.dicon");
}
public void testGet() {
YahooSearch rest = (YahooSearch) getComponent(YahooSearch.class);
YahooSearchDto dto = createDto();
String result = rest.getSearchResult(dto);
System.out.println(result);
}
private YahooSearchDto createDto() {
YahooSearchDto dto = new YahooSearchDto();
dto.setAppid("ApacheRestDemo");
dto.setQuery("Axis2 REST");
return dto;
}
}
|