intra-mart Accel Platform Webサービス Java開発プログラミングガイド 第3版 2017-04-01

Webサービス・プロバイダ の作成

作成手順の概要

この章では、Webサービス として公開する手順を説明します。
Webサービス として公開するJavaクラスを作成します。
Webサービス として公開するJavaクラスが実行されるまでの流れは以下の通りです。
../../_images/provider_7.png
  1. Webサービス・クライアント が、Webサービス の実行を要求します。
  2. Web サービス実行エンジン「Apache Axis2」が、受け付けたリクエストに該当するJavaクラスのメソッドを呼び出します。
  3. 実行結果を Webサービス・クライアント に返却します。

Webサービス のデプロイを準備する

開発環境を用意する

最初に Web サービスを提供するための資材を作成する開発環境を用意します。
このチュートリアルでは e Builder を使用して、以下のプロジェクトを作成し、開発を行う手順を説明します。
グループID mypackage (デフォルトの設定を使用)
バージョン 1.0.0 (デフォルトの設定を使用)
プロジェクト名 sample_provider
まず、e Builder、Resin、および、intra-mart Accel Platform をインストールして開発環境を構築してください。
インストール手順は「intra-mart e Builder for Accel Platform セットアップガイド」を参照してください。

注意

intra-mart Accel Platform をインストールする際、ベースモジュールから「Webサービス 認証・認可」と「Webサービス 認証・認可クライアント」モジュールを選択してください。
選択しない場合、チュートリアルの Java コードでコンパイルエラーが発生します。
e Builder のインストールが完了したら、以下の手順に従って、「Module Project」でプロジェクトを作成します。
  1. 「ファイル」-「新規」-「プロジェクト」をクリックします。
  2. 「e Builder」-「Module Project」を選択して「次へ」をクリックします。
  3. プロジェクト名に「sample_provider」を入力して、「終了」をクリックします。
プロジェクトの作成が完了したら、intra-mart Accel Platform の API を使用できるようにするために、プロジェクトの設定を行います。
  1. プロジェクトを右クリックして「プロパティ」を選択します。
  2. 「e Builder」-「Module Assembly」を選択します。
  3. Web アーカイブディレクトリに、war を展開してできたコンテキストパスと同名のフォルダを選択します。
  4. リソース変更時の自動デプロイ先の一覧で、全てのチェックボックスを外します。
  5. 「OK」をクリックします。

依存関係を解決する

プロジェクトの設定が完了したら、依存関係の修正を行います。
Webサービス・プロバイダ を作成するためには、「Webサービス 認証・認可」モジュールに依存する必要があります。
以下の手順に従って、プロジェクトの依存関係を修正します。
  1. 作成したプロジェクトのルートディレクトリに配置されている「module.xml」をダブルクリックします。

  2. 「依存関係」タブを開き、「追加」をクリックします。

  3. 以下の内容を入力して、「OK」をクリックします。

    ID jp.co.intra_mart.im_ws_auth
    バージョン 8.0.2

    コラム

    基本的にバージョンはサポートが行われている番号を指定します。
    使用したい API が他のバージョンに含まれている場合、そのバージョン番号を指定してください。
  4. module.xml ファイルを保存した後、「module.xml」タブを開き、不要なタグ(<tags>)を除去します。
    最終的に以下のようなソースに修正します。
    <?xml version="1.0" encoding="UTF-8"?>
    <module conf:schemaLocation="urn:intramart:jackling:toolkit:configurations configurations.xsd"
            xmlns="urn:intramart:jackling:module" xmlns:conf="urn:intramart:jackling:toolkit:configurations"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemeLocation="urn:intramart:jackling:module module.xsd">
    
        <id>mypackage.sample_provider</id>
        <version>1.0.0</version>
        <type>module</type>
        <name>${module.name}</name>
        <vendor>${module.vendor}</vendor>
        <description>${module.description}</description>
    
        <dependencies>
            <dependency>
                <module-id>jp.co.intra_mart.im_ws_auth</module-id>
                <verified-version min="8.0.2">8.0.2</verified-version>
            </dependency>
        </dependencies>
    </module>
    
  5. 「依存関係の階層」タブを開き、依存関係が解決されさまざまなモジュールが表示されていれば成功です。

Javaで業務処理を作成する

プロジェクトの準備が完了したら、Webサービス として公開するJavaクラスを作成し、業務処理を記述します。
今回作成するサンプルのWeb サービスでは、以下の形式のメンバ情報を保存・検索します。
プロパティ 説明(型)
id メンバID(String)
name メンバ名(String)
age 年齢(Integer)
married 既婚の場合 true、未婚の場合 false(Boolean)
birthDate 生年月日(Date)
children 子供情報(メンバ情報形式の配列)

型情報クラスを作成する

Web サービスで取り扱うJavaBeansを作成します。
以下の手順に従って、e Builder で型情報クラスを作成します。
  1. プロジェクトを右クリックして、「新規」-「クラス」を選択します。

  2. 以下の内容を入力して、「OK」をクリックします。

    パッケージ sample.web_service.provider
    名前 Member
  3. Member.java がプロジェクトの src/main/java 配下に作成されます。

  4. メンバ情報の各プロパティを保持するための private 変数、および、アクセサメソッドを定義します。

    package sample.web_service.provider;
    
    import java.io.Serializable;
    import java.util.Date;
    
    public class Member implements Serializable {
    
        // 用途に応じて、変更する必要がある場合は変更してください。
        private static final long serialVersionUID = 1L;
    
        private String id;
    
        private String name;
    
        private Integer age;
    
        private Boolean married;
    
        private Date birthDate;
    
        private Member[] children;
    
        public Integer getAge() {
            return age;
        }
    
        public Date getBirthDate() {
            return birthDate;
        }
    
        public Member[] getChildren() {
            return children;
        }
    
        public String getId() {
            return id;
        }
    
        public Boolean getMarried() {
            return married;
        }
    
        public String getName() {
            return name;
        }
    
        public void setAge(final Integer age) {
            this.age = age;
        }
    
        public void setBirthDate(final Date birthDate) {
            this.birthDate = birthDate;
        }
    
        public void setChildren(final Member[] children) {
            this.children = children;
        }
    
        public void setId(final String id) {
            this.id = id;
        }
    
        public void setMarried(final Boolean married) {
            this.married = married;
        }
    
        public void setName(final String name) {
            this.name = name;
        }
    
    }
    

コラム

当サンプルではメンバ情報をPermanent APIで扱うため、Member クラスは Serializable インタフェースを実装しています。

注意

Web サービスとして公開するメソッドの引数、および、返却値に、継承関係を持つクラスを使用しないでください。
継承関係を持ったクラスを使用すると、Web サービスのクライアント側でエラーが発生します。
これは、Java オブジェクトが XML に変換される際、XML 名前空間がサブクラスで統一される ADB(Axis Data Binding)の仕様による制限です。
例えば、以下の SubModel が ParentModel の子クラスとして定義されている場合、SubModel は Web サービスとして公開するメソッドの引数、および、返却値として使用できません。
  • sample.foo.ParentModel
  • sample.bar.SubModel

Web サービス処理を実装する

sample.web_service.provider.MemberInfoOperatorService.java を用意します。
このクラスに定義されているメソッド「add()」、「find()」、および、「findAll()」を Web サービスとして公開します。
以下の手順に従って、e Builder で Webサービス として公開するJavaクラスを作成します。
  1. プロジェクトを右クリックして、「新規」-「クラス」を選択します。

  2. 以下の内容を入力して、「OK」をクリックします。

    パッケージ sample.web_service.provider
    名前 MemberInfoOperatorService
  3. MemberInfoOperatorService.java がプロジェクトの src/main/java 配下に作成されます。

  4. MemberInfoOperatorService.java を実装します。

    MemberInfoOperatorService.java のソースは以下の通りです。
    package sample.web_service.provider;
    
    import java.io.IOException;
    import java.util.List;
    
    import jp.co.intra_mart.foundation.service.client.information.PermanentDirectory;
    import jp.co.intra_mart.foundation.service.client.information.TreasureFile;
    import jp.co.intra_mart.foundation.web_service.auth.WSUserInfo;
    
    import org.apache.axis2.AxisFault;
    
    public class MemberInfoOperatorService {
    
        private static final String DOMAIN = "sample_web_service";
    
        private static final String GROUP = "sample_member_info";
    
        public Boolean add(final WSUserInfo wsUserInfo, final Member member) throws AxisFault {
            final TreasureFile<Member> treasure = getPermanentFile();
            try {
                treasure.put(member.getId(), member);
                return Boolean.TRUE;
            } catch (final IOException e) {
                throw AxisFault.makeFault(e);
            } catch (final ClassNotFoundException e) {
                throw AxisFault.makeFault(e);
            }
        }
    
        public Member find(final WSUserInfo wsUserInfo, final String id) throws AxisFault {
            final TreasureFile<Member> treasure = getPermanentFile();
            try {
                final Member member = treasure.get(id);
                return member;
            } catch (final IOException e) {
                throw AxisFault.makeFault(e);
            } catch (final ClassNotFoundException e) {
                throw AxisFault.makeFault(e);
            }
        }
    
        public Member[] findAll(final WSUserInfo wsUserInfo) throws AxisFault {
            final TreasureFile<Member> treasure = getPermanentFile();
            try {
                final List<String> keyList = treasure.keyList();
                final int size = keyList.size();
                final Member[] members = new Member[size];
                for (int i = 0; i < size; i++) {
                    members[i] = treasure.get(keyList.get(i));
                }
                return members;
            } catch (final IOException e) {
                throw AxisFault.makeFault(e);
            } catch (final ClassNotFoundException e) {
                throw AxisFault.makeFault(e);
            }
        }
    
        private TreasureFile<Member> getPermanentFile() {
            return PermanentDirectory.getInstance(DOMAIN).getFile(GROUP);
        }
    
    }
    

コラム

メンバ情報の保存は Permanent API を利用します。

コラム

AxisFault をスローすることで、スローした内容を Webサービス・クライアント に返信できます。
AxisFaultの詳細は、「Axis2のAPIドキュメント」を参照してください。

services.xml を作成する

Webサービス 実装クラスの作成が完了したら、Web サービスの設定ファイル「services.xml」を用意します。
<services.xml>ファイルを、プロジェクトの以下の場所に作成します。
  • src/main/webapp/WEB-INF/services/sample_member_info/META-INF/services.xml
services.xml のソースは以下の通りです。
<?xml version="1.0" encoding="UTF-8"?>
<serviceGroup>
    <service name="SampleMemberInfoOperatorService">
        <parameter name="ServiceClass">sample.web_service.provider.MemberInfoOperatorService</parameter>
        <module ref="im_ws_auth"/>
        <messageReceivers>
            <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only" class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver" />
            <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"  class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
        </messageReceivers>

        <parameter name="authz-uri">service://intra-mart.jp/public-resources/welcome-to-intramart</parameter>

        <operation name="add">
            <parameter name="authz-uri">service://intra-mart.jp/public-resources/welcome-to-intramart</parameter>
        </operation>

        <operation name="find">
            <parameter name="authz-uri">service://intra-mart.jp/public-resources/welcome-to-intramart</parameter>
        </operation>

        <operation name="findAll">
            <parameter name="authz-uri">service://intra-mart.jp/public-resources/welcome-to-intramart</parameter>
        </operation>
    </service>
</serviceGroup>

コラム

各関数に、アクセス権限を設定するための認可の「リソースURI」を設定します。
最初はサンプルの動作を確認するために、未認証・認証済みを問わず、どのユーザでもアクセス可能なリソースURIを割り当てます。
  • service://intra-mart.jp/public-resources/welcome-to-intramart
実際に Web サービスを業務利用する場合は、個別の「リソースURI」を用意してください。
権限設定の詳細は、後述の「認可を利用してアクセス権限を設定する」を参照してください。

Webサービス をデプロイする

資材をデプロイする

以上で Web サービスを提供するための資材が完成しました。
次に作成したモジュールをユーザモジュールとして取り込み、war を作成して Resin にデプロイします。
以下の手順に従って、e Builder でユーザモジュールを作成します。
  1. プロジェクトを右クリックして、「エクスポート」を選択します。
  2. 「e Builder」-「imm file」を選択して、「次へ」をクリックします。
  3. 出力先フォルダに任意の場所を選択して、「終了」をクリックします。
  4. しばらくすると、出力先フォルダに <sample_provider-1.0.0.imm> ファイルが作成されます。
次に、以下の手順に従って、e Builder で imm ファイルをユーザモジュールとして取り込みます。
  1. e Builder で環境構築時に利用したプロジェクトの「juggling.im」を開きます。

  2. 「ユーザモジュール」タブを開き、右上の「モジュールを追加します」アイコンをクリックします。

  3. e Builder で作成した <sample_provider-1.0.0.imm> ファイルを選択して開きます。

    コラム

    依存関係が不足している場合、上側にエラーメッセージが表示されます。
    この場合、エラーメッセージをクリックして不足しているモジュールを追加してください。
  4. juggling.im を保存して、環境構築時と同じ手順で war を作成し、Resin にデプロイします。

  5. Resin を再起動します。

次に、以下の手順に従って、テナント環境セットアップを実施します。
  1. システム管理画面を開き、システム管理者でログインします。
    http://<HOST>:<PORT>/<CONTEXT_PATH>/system/login
  2. 「テナント環境セットアップ」をクリックします。

    コラム

    テナント環境が最新であり、セットアップが必要なモジュールがない旨のメッセージが表示されている場合は、以降の操作は不要です。
  3. 続けて「テナント環境セットアップ」をクリックします。

  4. 確認メッセージで「決定」をクリックします。

デプロイされていることを確認する

Resin の再起動とテナント環境セットアップが完了したら、作成した Web サービスがデプロイされていることを確認します。
以下の手順に従って、正常にデプロイされていることを確認します。
  1. 以下の URL にアクセスします。
    http://<HOST>:<PORT>/<CONTEXT_PATH>/services/listServices
  2. 「SampleMemberInfoOperatorService」に「Service Status : Active」の文字列と、各関数名が表示されていることが確認できれば成功です。

    ../../_images/provider_3.png

認可を利用してアクセス権限を設定する

ここまでのチュートリアルでは、 Web サービスに割り当てた認可のリソースURIは、未認証・認証済みを問わず、どのユーザでもアクセス可能なものを割り当てました。
  • service://intra-mart.jp/public-resources/welcome-to-intramart
Web サービスを正式版として提供する際は、Web サービスのアクセス権限を細かく設定できるようにするために、認可リソースを登録します。
Web サービスの場合、認可リソースのキーとなる「リソースURI」のスキームは、通常「service」を利用します。
例えば、以下のようにリソースURI を定義します。
  • service://sample_provider/web_service/member_info_operator
Web サービスの各関数に対して個別に権限設定を分けて管理したい場合、各関数にリソースURI を定義します。
例えば、サンプルの Web サービスで公開した「add()」、「find()」、「findAll()」のそれぞれで権限設定を分けたい場合は、3つのリソースを作成するためにそれぞれ「リソースURI」を定義します。
  • service://sample_provider/web_service/member_info_operator/add
  • service://sample_provider/web_service/member_info_operator/find
  • service://sample_provider/web_service/member_info_operator/findAll

認可リソースを作成する

権限設定を行うための「リソースURI」が決定したら、テナント環境セットアップ資材を作成します。
必要な資材は以下の通りです。
  • 認可リソース設定ファイル
  • テナント環境セットアップを実施するためのセットアップ設定ファイル
この章では、認可に以下の構成でリソースを登録します。
../../_images/provider_2.png

コラム

認可リソースは、テナント環境セットアップの資材からではなく、テナント管理機能の「認可設定画面」から登録することもできます。
Web サービスの開発中に認可リソースを頻繁に変更する可能性がある場合は、認可設定画面から設定すると便利です。
認可設定画面を操作する方法についての詳細は「テナント管理者操作ガイド」-「認可を設定する」の「リソースを追加する」を参照してください。
それぞれ必要な資材を、プロジェクトの以下の場所に作成します。 サンプルの資材内容は以下の通りです。
  • 認可リソース設定ファイル

    src/main/storage/system/products/import/basic/sample_provider/sample_provider-authz-resource.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <root xmlns="http://www.intra-mart.jp/authz/imex/resource">
    
        <authz-resource id="sample_provider-service" uri="service://sample_provider/web_service/member_info_operator">
            <display-name>
                <name locale="ja">SampleMemberInfoOperatorService</name>
            </display-name>
            <parent-group id="web-services" />
        </authz-resource>
    
        <authz-resource uri="service://sample_provider/web_service/member_info_operator/add">
            <display-name>
                <name locale="ja">add</name>
            </display-name>
            <parent-group id="sample_provider-service" />
        </authz-resource>
    
        <authz-resource uri="service://sample_provider/web_service/member_info_operator/find">
            <display-name>
                <name locale="ja">find</name>
            </display-name>
            <parent-group id="sample_provider-service" />
        </authz-resource>
    
        <authz-resource uri="service://sample_provider/web_service/member_info_operator/findAll">
            <display-name>
                <name locale="ja">findAll</name>
            </display-name>
            <parent-group id="sample_provider-service" />
        </authz-resource>
    
    </root>
    

    コラム

    Web サービス自身と、各関数に割り当てた「リソースURI」分、認可リソースを作成します。
    Web サービスに関係する認可リソースを登録するための親リソースグループ「web-services」が初期状態で用意されています。
    そのため、サンプルの Web サービスのトップ階層となる「SampleMemberInfoOperatorService」の親リソースグループを「web-services」に設定します。
  • テナント環境セットアップを実施するためのセットアップ設定ファイル

    src/main/conf/products/import/basic/sample_provider/import-sample_provider-config-1.xml
    <import-data-config xmlns="http://intra_mart.co.jp/system/service/provider/importer/config/import-data-config"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://intra_mart.co.jp/system/service/provider/importer/config/import-data-config import-data-config.xsd">
    
        <tenant-master>
            <authz-resource-file>products/import/basic/sample_provider/sample_provider-authz-resource.xml</authz-resource-file>
        </tenant-master>
    
    </import-data-config>
    

services.xml を変更する

セットアップ資材の作成が完了したら、Web サービスの各関数にアクセスするための権限設定ファイル(services.xml)を変更します。
  • src/main/webapp/WEB-INF/services/sample_member_info/META-INF/services.xml
service://intra-mart.jp/public-resources/welcome-to-intramart の部分を、定義した「リソースURI」に書き換えます。
services.xml のソースは以下の通りです。
<?xml version="1.0" encoding="UTF-8"?>
<serviceGroup>
    <service name="SampleMemberInfoOperatorService">
        <parameter name="ServiceClass">sample.web_service.provider.MemberInfoOperatorService</parameter>
        <module ref="im_ws_auth"/>
        <messageReceivers>
            <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only" class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver" />
            <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"  class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
        </messageReceivers>

        <parameter name="authz-uri">service://sample_provider/web_service/member_info_operator</parameter>

        <operation name="add">
            <parameter name="authz-uri">service://sample_provider/web_service/member_info_operator/add</parameter>
        </operation>

        <operation name="find">
            <parameter name="authz-uri">service://sample_provider/web_service/member_info_operator/find</parameter>
        </operation>

        <operation name="findAll">
            <parameter name="authz-uri">service://sample_provider/web_service/member_info_operator/findAll</parameter>
        </operation>
    </service>
</serviceGroup>

コラム

services.xml の設定内容については「Webサービス 認証・認可 仕様書」-「services.xmlについて」もあわせて参照してください。

資材を再デプロイする

Web サービスの設定ファイルの更新が完了したら、再デプロイを行います。
資材をデプロイする」の手順に従って、 sample_provider-1.0.0.imm を再デプロイしてください。

注意

デプロイ後、システム管理画面から、テナント環境セットアップを必ず実行してください。

認可で権限設定を行う

再デプロイが完了したら、認可設定画面を開いて実際に Web サービスに対してアクセス権限を設定します。
以下の手順に従って、アクセス権限を設定します。
  1. 一般利用者のログイン画面を開き、テナント管理者でログインします。
    http://<HOST>:<PORT>/<CONTEXT_PATH>/login
  2. サイトマップを開き、「テナント管理」カテゴリから「認可」をクリックします。

    ../../_images/provider_4.png

  3. 「リソースの種類」から「Web サービス」を選択します。

    ../../_images/provider_5.png

  4. 認可設定のグリッドに「SampleMemberInfoOperatorService」とその配下に「add」、「find」、および、「findAll」が表示されていることを確認します。

    ../../_images/provider_6.png

  5. 「add」、「find」、および、「findAll」に対して、任意の対象者条件に権限を設定します。

コラム

権限の設定方法についての詳細は「テナント管理者操作ガイド」-「認可を設定する」を参照してください。
実際に設定したアクセス権限通りに動作するかどうかを確認するためには、「Webサービス・クライアント」を用意する必要があります。