Seasar DI Container with AOP

S2Axis2 RESTの利用

Axis2では、REST(Representational State Transfer)に対応した形式でサービスをデプロイしたり、そのサービスにアクセスすることが可能です。 本ドキュメントはS2Axis2におけるRESTの利用方法について記述しています。

目次

Axis2におけるRESTful Serviceの特徴

RESTに対応したWebサービスをRESTFul Serviceと言いますが、Axis2でのRESTFul Serviceは以下のような特徴があります。

  1. 同期型要求応答形式(Request/Response)である。
  2. GETでアクセスする場合、サービスやメソッドはURLに基づいて解釈されます。GETのパラメータは、そのままサービスのパラメータとなります。
  3. POSTでアクセスする場合、SOAP EnvelopeやSOAP Bodyは不要です。ヘッダも不要であり、ペイロード(送信データとなるパラメータ群)を直接送信します。

注意点としては、GET/DELETEではシンプルタイプ(プリミティブ型およびそのラッパ型、java.util.Date/java.util.Calendarの日付型)のみしか、 サービスのパラメータには利用できません。JavaBeanなどのオブジェクトクラスをサービスのパラメータとして利用する場合は、 POST/PUTを利用する必要があります(戻り値にオブジェクトクラスを利用するのは可能です)。

サーバ側の設定

デプロイ対象のサービスクラス

S2Axis2でデプロイしたサービスは、デフォルトの状態でRESTに対応しています。 また、インタフェースを定義することで、外部のサービスにREST形式でアクセスすることも可能です。

デプロイ済みのサービスに対して、以下のようにURLを指定することで、アクセスが可能です(GETでのアクセス)。

http://localhost:8080/s2axis2-examples/services/Echo/echo?id=1&message=test

実行すると、以下のような結果が返ってきます。 SOAPの形式ではなく、単にXML形式のデータが返ってきていることが分かります。

<ns:echoResponse xmlns:ns="http://ex01.examples.axis2.remoting.seasar.org">
  <ns:return>[id = 1] test</ns:return> 
</ns:echoResponse>

クライアント側の設定

REST形式でサービスにアクセスする場合は、専用のConnectorを利用します。

<include path="s2axis2-client.dicon"/>

<component name="remoting"
           class="org.seasar.remoting.common.interceptor.RemotingInterceptor" />

<component name="connector" class="org.seasar.remoting.axis2.connector.RESTConnector">
    <property name="baseURL">baseURL</property>
    <property name="appendAction">true</property>
</component>

<component class="org.seasar.remoting.axis2.examples.rest.ex01.RESTfulEcho">
    <aspect>remoting</aspect>
</component>

リクエストの構築

dicon定義(クライアント側)

Axis2でデプロイされたサービスにREST形式でアクセスする場合、URLは以下の形式になります。

http://<host>:<port>/<contextPath>/services/<serviceName>/<methodName>

「http://<host>:<port>/<contextPath>/services/<serviceName>/」の部分は、dicon定義のbaseURLで指定し、 「serviceName」は呼び出すサービスのクラス名となります。

さらに、上記のようにメソッド名を付加する必要がありますが、そのような場合は、 クライアント側のdiconで以下のようにappendActionプロパティを設定する必要があります。

<component name="connector" class="org.seasar.remoting.axis2.connector.RESTConnector">
    <property name="baseURL">baseURL</property>
    <property name="appendAction">true</property>
</component>

これは、通常RESTFul Serviceでは、メソッド名は使用せずにリソース名(=サービス名)とパラメータのみで呼び出しを行われることが多いのですが、 Axis2は仕様としてメソッド名を付加する必要があるため、外部サービスなどを呼び出す場合とアクセスするURLに差分ができてしまいます。 そのため、S2Axis2では、このようなプロパティを指定するようにしています。

パラメータの指定

リクエストパラメータは、呼び出すサービスのメソッド引数を利用して構築されます。サービスのメソッドの引数は、 1つのDTO(setter/getterを保持するJavaBeanクラス)として指定するか、シンプルタイプのパラメータ(複数可)として指定します。

また、リクエストを構築する上で、アノテーションを利用することにより、より細かな指定が可能となります。 詳細は、RESTに関するアノテーションを参照してください。

DTOとしてパラメータを指定する場合

以下のように、サービスのメソッド引数がDTOの場合の例を示します。

public interface RESTfulBeanEcho {
    EchoDto postEchoByBean(EchoDto dto);
}
public class EchoDto {
    private Integer id;
    private String  message;


    // setter/getter
}

上記のサービスを呼び出した場合、HTTPリクエストは以下のようになります。 EchoDtoのパラメータ名が、そのままリクエストのパラメータに利用されます。

POST /s2axis2-examples/services/RESTfulBeanEcho/postEchoByBean HTTP/1.1
Content-Type: application/xml; charset=UTF-8
SOAPAction: urn:postEchoByBean
User-Agent: Axis2
Host: 127.0.0.1:8088


<postEchoByBean xmlns="http://ex01.rest.examples.axis2.remoting.seasar.org">
    <echoDto xmlns="" type="org.seasar.remoting.axis2.examples.rest.ex01.EchoDto">
        <id>1</id>
        <message>メッセージ</message>
    </echoDto>
</postEchoByBean>
シンプルタイプのパラメータを指定する場合

以下のように、サービスのメソッド引数がシンプルタイプである場合の例を示します。 この場合、必ず@RestUriParamアノテーションを指定してください。

public interface RESTfulEcho {
    EchoDto postEcho(@RestUriParam("id") Integer id, @RestUriParam("message") String message);
}

上記のサービスを呼び出した場合、HTTPリクエストは以下のようになります。 @RestUriParamアノテーションで指定したパラメータ名が、リクエストのパラメータに利用されます。

POST /s2axis2-examples/services/RESTfulEcho/postEcho HTTP/1.1
Content-Type: application/xml; charset=UTF-8
SOAPAction: urn:postEcho
User-Agent: Axis2
Host: 127.0.0.1:8088
Transfer-Encoding: chunked


<postEcho xmlns="http://ex01.rest.examples.axis2.remoting.seasar.org">
    <id xmlns="">1</id>
    <message xmlns="">メッセージ</message>
</postEcho>

HTTPメソッド/Content-Typeの判別

RESTFul Serviceには、POST/GET/PUT/DELETEのHTTPメソッドを指定してサービスにアクセスすることになりますが、 S2Axis2では、呼び出すサービスのメソッド名から、自動的に上記のHTTPメソッドやその際に利用されるContent-Typeを判別します。

呼び出すサービスのメソッドの命名規則
処理 HTTPメソッド Content-Type メソッドの接頭文字列
挿入 POST application/xml post, create, insert, add
更新 PUT application/xml update, modify, store
削除 DELETE application/x-www-form-urlencoded delete, remove
取得 GET application/x-www-form-urlencoded 上記以外

HTTPメソッド/Content-Typeに対しても、アノテーションを利用することにより、より細かな指定が可能となります。 詳細は、RESTに関するアノテーションを参照してください。

外部サービスの呼び出し

サービスのインタフェースのみを定義することで、外部サービスを呼び出すことが可能です。 ここでは、AmazonのWebサービスを呼び出す例を示します。

サービスのインタフェース

ここでは、インタフェースやメソッド、DTOのプロパティにアノテーションを指定することによって、 デフォルトの設定を変更しています。

@RestUriTemplate("/onca/xml3")
public interface AmazonSearch {

    @RestMethod(contentType = "application/x-www-form-urlencoded")
    String postSearchResult(AmazonSearchDto dto);

    String getSearchResult(AmazonSearchDto dto);
}
public class AmazonSearchDto {
    private String t;
	
    @RestUriParam("dev-t")
    private String devT;
	
    @RestUriParam("AsinSearch")
    private String asinSearch;
    
    private String locale;
    
    private String type;
    
    private String f;
	
    // setter/getter
}
クライアント
public class AmazonSearchClient {

    AmazonSearch restService;
	
    public void executePost() {

        AmazonSearchDto dto = createDto();
        String result = restService.postSearchResult(dto);
		
        System.out.println(result);
    }


    private AmazonSearchDto createDto() {
        AmazonSearchDto dto = new AmazonSearchDto();
        dto.setT("webservice-20");
        dto.setDevT("xxxxx");
        dto.setAsinSearch("4774128554");
        dto.setLocale("jp");
        dto.setType("heavy");
        dto.setF("xml");
		
        return dto;
    }
}
dicon定義
最終的にアクセスしたいURLが「http://xml-jp.amznxslt.com/onca/xml3」であるため、サービス名で指定した「/onca/xml3」を除いたURLを、 baseURLとして定義します。
<include path="s2axis2.dicon" />

<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://xml-jp.amznxslt.com/")
    </property>
</component>

<component class="org.seasar.remoting.axis2.examples.rest.amazon.AmazonSearch">
    <aspect>remoting</aspect>
</component>