4.0
Java/JSP版

1. 概要

Java/JSPを利用して実装されたサンプルアプリケーションです。

2. セットアップ

サンプルアプリケーションのセットアップに関する説明です。
もし、既にiPLAssの開発環境の構築チュートリアルを実行できており、サンプルアプリケーションを動かしたい場合、以下の手順に従って実施してください。
それ以外の場合は、開発環境の構築を先に実施することをお勧めします。

  • サンプルアプリケーションのプロジェクトをGitHubから取得してプロジェクトを作成します。プロジェクトの作成手順はプロジェクトの作成を参照してください。

    サンプルコードで Java21 より上のバージョンのスタイルでコーディングする場合は build.gradle の javaVersion を使用したい Java のバージョンに書き換えてください。
    書き換えた後はGradleプロジェクトのリフレッシュを行い、エラーが出ないことを確認してください。

    build.gradle
    apply plugin: 'java'
    apply plugin: 'war'
    apply plugin: 'eclipse-wtp'
    
    ext {
        javaVersion = JavaVersion.VERSION_21 (1)
    }
    
    ----------------------------------------以下略----------------------------------------
    1 必要に応じて使用したい Java のバージョンに書き換えます。
  • テナントの作成

    このサンプルアプリは開発環境の構築の章で作成したテナントで動かすことを想定しています。もし新規テナントで サンプルアプリを起動したい場合、以下の手順を実施してください。
    • mtp-service-config.xmlに以下の設定を入れます。

          <!-- Rdb Connection Settings -->
          <service>
              <interface>org.iplass.mtp.impl.rdb.connection.ConnectionFactory</interface>
      
              <!-- DataSource base ConnectionFactory -->
              <!-- <class>org.iplass.mtp.impl.rdb.connection.DataSourceConnectionFactory</class> --> (1)
              <!-- <property name="dataSourceName" value="java:comp/env/jdbc/iplass" /> --> (1)
      
              <!-- DriverManager base ConnectionFactory -->
              <class>org.iplass.mtp.impl.rdb.connection.DriverManagerConnectionFactory</class> (2)
              <!-- for mysql -->
              <property name="url" value="jdbc:mysql://[host]:[port]/[schema]" />
              <property name="user" value="XXXXX" /> (3)
              <property name="password" value="XXXXX" /> (3)
              <property name="driver" value="com.mysql.cj.jdbc.Driver" /> (4)
      
              <!-- if sql execution exceeds this milliseconds, log sql by warn level.(0 means no log by warn level) -->
              <property name="warnLogThreshold" value="0" />
      
              <!-- If change transaction isolation level on create connection, set below. -->
              <!--
              <property name="transactionIsolationLevel" value="READ_COMMITTED" />
               -->
      
          </service>
      1 データソース利用に関する設定項目をコメントアウトします。
      2 DriverManager利用に関する設定項目を追加します。
      3 テナント作成時はDBA権限を持つユーザーを設定してください。
      4 クラスパスが通っている場所にJDBCドライバを配置します。
    • サンプルアプリのルートパスの下で 、

      1. Gradleタスクの runTenantBatch を実行します。

      2. 起動した画面で Create Default Tenant をクリックします。

      3. ダイアログで name(テナント名)AdminUserId(管理者ユーザーID)AdminUserPassword(管理者ユーザーパスワード) を入力し、 Create をクリックします。

サンプルアプリでは、データベースへの接続方法にDataSourceを利用することを想定していますが、テナントを作成する処理の runTenantBatch タスクではDataSourceに関する設定を利用できないため、一時的に接続方法をDataSource利用からDriverManager利用に変えます。テナント作成後は、再度DataSourceを利用する設定に戻してください。
  • 以下のサンプルアプリの起動手順を順に実施してください。

サンプルアプリの起動手順
  1. サンプルアプリでは、DataSourceを利用するため、mtp-service-config.xmlでDataSource名を設定します。また、Tomcatのコンテキスト設定にDataSourceの接続情報を入れます。
    また、Tomcatの lib フォルダに利用するDBに該当するJDBCドライバを入れます。

    ファイル名

    /src/main/resources/mtp-service-config.xml

    <!-- Rdb Connection Settings -->
    <service>
        <interface>org.iplass.mtp.impl.rdb.connection.ConnectionFactory</interface>
    
        <!-- DataSource base ConnectionFactory -->
        <class>org.iplass.mtp.impl.rdb.connection.DataSourceConnectionFactory</class>
        <property name="dataSourceName" value="java:comp/env/jdbc/iplass" /> (1)
    
    
        <!-- if sql execution exceeds this milliseconds, log sql by warn level.(0 means no log by warn level) -->
        <property name="warnLogThreshold" value="0" />
    
        <!-- If change transaction isolation level on create connection, set below. -->
        <!--
        <property name="transactionIsolationLevel" value="READ_COMMITTED" />
        -->
    
    </service>
    1 サンプルアプリ実行用のDataSource名

    開発環境の構築の章で作成したデータベースの接続情報をインストールしたTomcatの次の設定ファイルに入れます。

    %CATALINA_HOME%\conf\context.xml
    <?xml version="1.0" encoding="UTF-8"?>
    
        <WatchedResource>WEB-INF/web.xml</WatchedResource>
        <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
    
         <Resource name="jdbc/iplass" auth="Container" type="javax.sql.DataSource"
                maxTotal="100" maxIdle="30" maxWaitMillis="10000"
                username="XXXXX" password="XXXXX" driverClassName="com.mysql.cj.jdbc.Driver"
                url="jdbc:mysql://[host]:[port]/[schema]"/> (1)
    
    </Context>
    1 Tomcatのコンテキスト設定に該当するデータベースの接続情報を入れます。
  2. サンプルアプリでは、全文検索機能(lucene)を利用するため、mtp-service-config.xmlに記載のあるINDEXファイルの保存場所をローカル環境の適当な場所に変えます。

    ファイル名

    /src/main/resources/mtp-service-config.xml

    <service>
        <interface>org.iplass.mtp.impl.fulltextsearch.FulltextSearchService</interface>
        <property name="useFulltextSearch" value="true" /> (1)
        <property name="maxRows" value="1000" />
        <property name="throwExceptionWhenOverLimit" value="true"/>
    
        <!-- lucene利用 -->
        <class>org.iplass.mtp.impl.fulltextsearch.lucene.LuceneFulltextSearchService</class>
        <property name="directory" value="[set your lucene index file store path. eg: D:\tmp\lucene]" /> (2)
        <property name="analyzer" value="org.apache.lucene.analysis.ja.JapaneseAnalyzer" />
        <property name="indexWriterRAMBufferSizeMB" value="64.0"/>
        <property name="redundantTimeMinutes" value="10"/>
    </service>
    1 useFulltextSearchをtrueに設定します。
    2 INDEXファイル保存場所をローカルパスの適当な場所に設定します。
  3. Tomcatを起動し、http://localhost:8080/コンテキスト名/テナント名/gem/ にアクセスすると、ログイン画面が表示されます。管理者ユーザーIDとパスワードでログインします。

  4. Admin Consoleの Packaging 機能を利用して、プロジェクトの sample-data フォルダにあるサンプル実行用のデータをインポートします。

    「entitydata.zip」ファイルを、Admin Consoleの「Packaging」ツールで取り込んでください。

    sample ec java jsp setup package upload

    デフォルトの設定で「Import」ボタンを押下してください。

    sample ec java jsp setup package import

    Importを実行すると「Log」パネルに処理状況が表示されます。処理が終了したタイミングでエラーが発生していないことを確認してください。

    sample ec java jsp setup package import logpanel

    新たに作成したロールなどを反映させるために、MetaDataSettingsメニューの右上の「MetaDataのリフレッシュ」アイコンをクリックします。

    sample ec java jsp setup metadata refresh
  5. Admin Consoleのテナント情報の多言語利用設定で、「日本語」と「English」にチェックを入れます。

    sample ec java jsp setup tenant multilingual

    「Save」ボタンを押してください。

    sample ec java jsp setup tenant multilingual save
  6. Admin ConsoleでEntityExplorerの Entity Crawl 機能を利用して全文検索のINDEXデータを作成します。
    詳細については、全文検索を参照してください。

    ToolsのEntityExplorerを選択します。

    sample ec java jsp setup entityexplorer

    全文検索を利用する設定になっている場合、「Entity Crawl」タブが表示されます。

    sample ec java jsp setup entityexplorer tabs

    A) 任意のEntityのみを対象としてクローリングしたい場合は、リストの対象Entityにチェックを入れて、「Start Crawl」ボタンをクリックしてください。

    B) クローリング対象Entityをすべてクローリングしたい場合は「Re Crawl All Entity」ボタンをクリックしてください。

    C) クローリングが完了したら、最新のINDEXデータを反映させるために、「Refresh」ボタンをクリックしてください。

    sample ec java jsp setup entityexplorer crawl
  7. 上記起動手順の実施が完了しましたら、サンプルアプリのグローバル設定を確認してください。

3. 機能

3.1. Top画面の作成

  • レイアウトの利用
    Top画面の構成は下図のようになっています。画面共通で利用する2つのレイアウト用テンプレート defaultLayoutshippingLayout を用意し、画面のメインエリアは機能に併せて呼びだす形にしています。ここでは画面のメインエリアに top テンプレートを利用しています。

    sample ec java jsp template layout

    ファイル

    src/main/webapp/jsp/samples/ec01/layout/defaultLayout.jsp

    <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
    <%@ page import="org.iplass.mtp.web.template.TemplateUtil"%>
    <%@ page import="samples.ec01.utils.URLHelper" %>
    <%@ taglib prefix="m" uri="http://iplass.org/tags/mtp"%> (1)
    <%@ taglib prefix="c" uri="jakarta.tags.core"%>
    
    ----------------------------------------以上略----------------------------------------
            <!-- 小さい画面で表示 end-->
            <div class="row layout-container">
                <div class="col-md-3 d-none d-md-block">
                    <div class="row">
                        <div class="col-12">
                            <div class="list-group list-group-flush">
                                <a href="${m:tcPath()}/samples/ec01/top" class="list-group-item list-group-item-action fw-bold border-top">${m:rs('iplass-wtp-messages', 'samples.ec01.layout.defaultLayout.home')}</a>
                                <c:forEach var="category" items="${categoryList}">
                                    <a href="${URLHelper.getCategoryPath(category.oid)}" class="list-group-item list-group-item-action">${category.name}</a>
                                </c:forEach>
                            </div>
                        </div>
                    </div>
                </div>
                <div class="col-sm-12 col-md-9">
                    <m:renderContent /> (2)
                </div>
            </div>
            <hr>
            <div class="row">
                <div class="col-12">
                    <ul class="list-group">
                        <li class="list-group-item border-0 fw-bold">Links</li>
                        <li class="list-group-item border-0">
                            <a href="${m:tcPath()}/samples/ec01/news/newInfo" class="text-dark">${m:rs('iplass-wtp-messages','samples.ec01.layout.defaultLayout.news')}</a>
                        </li>
                        <li class="list-group-item border-0">
                            <a href="${m:tcPath()}/samples/ec01/search/search" class="text-dark">${m:rs('iplass-wtp-messages','samples.ec01.layout.defaultLayout.search')}</a>
                        </li>
                        <li class="list-group-item border-0">
                            <a href="${m:tcPath()}/samples/ec01/inquiry/inquiry" class="text-dark">${m:rs('iplass-wtp-messages','samples.ec01.layout.defaultLayout.inquiry')}</a>
                        </li>
                        <li class="list-group-item border-0">
                            <a href="${m:tcPath()}/samples/ec01/shop/tradeLaw" class="text-dark">${m:rs('iplass-wtp-messages','samples.ec01.layout.defaultLayout.SCTAInfo')}</a>
                        </li>
                    </ul>
                </div>
            </div>
    ----------------------------------------以下略----------------------------------------
    1 iPLAssのJSPタグライブラリ
    2 LayoutテンプレートのJSPにおいて、メインコンテンツを表示する箇所を指定するJSPタグです。
  • メタデータ定義ファイル

    ファイル名

    samples-ec01-ce-metadata.xml

    <contextPath name="/template">
    ----------------------------------------以上略----------------------------------------
        <!-- レイアウト -->
        <metaDataEntry>
            <metaData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xsi:type="metaJspTemplate">
                <name>samples/ec01/layout/defaultLayout</name>
                <displayName>標準レイアウト</displayName>
                <path>/jsp/samples/ec01/layout/defaultLayout.jsp</path> (1)
                <contentType>text/html; charset=utf-8</contentType>
            </metaData>
        </metaDataEntry>
        ......
        <metaDataEntry>
            <metaData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xsi:type="metaJspTemplate">
                <name>samples/ec01/top</name>
                <displayName>Top画面</displayName>
                <path>/jsp/samples/ec01/top.jsp</path> (2)
                <layoutId>/action/samples/ec01/layout/defaultLayout</layoutId> (3)
                <contentType>text/html; charset=utf-8</contentType>
            </metaData>
        </metaDataEntry>
    
    
    ----------------------------------------以下略----------------------------------------
    1 レイアウト用のテンプレートファイルを指定しています。
    2 Top画面用のテンプレートファイルを指定しています。
    3 Top画面のテンプレートでは、 layoutId にレイアウト用テンプレートを指定しています。

3.2. Bean/Bean Validation

iPLAssのBean/Bean Validation機能を利用する場合、バリデーションチェックしたいBeanクラスのプロパティにアノテーションをつけることで、バリデーションが自動で実行されます。また、バリデーション結果を画面に表示できます。

サンプルアプリの問い合わせ登録画面で入力された値に対してバリデーションが実行される機能を例として説明していきます。

  • 必要なJavaクラスを作成します。
    プロジェクトのフォルダ src/main/java/samples/ec01/bean を開きます。

    src.main.java
        ┗ samples.ec01
            ┣ bean
            ┗ annotation (1)
                ┃   ┣ Kana.java
                ┃   ┗ ......         
                ┣ ui
                ┣ validator (2)
                ┃   ┣ group (3)
                ┃   ┃   ┗ JapaneseChecks.java
                ┃   ┣ KanaValidator.java
                ┃   ┗ ......
                ┣━ UserBean.java (4)
                ┗ ......
    1 カスタムのバリデーション
    カスタムのバリデーションを samples.ec01.bean.annotation.Kana に記述します。カスタムのバリデーターで利用されています。
    2 カスタムのバリデーター
    カスタムのバリデーターを samples.ec01.bean.validator.KanaValidator に記述します。カスタムのバリデーションで利用されています。
    3 カスタムのバリデーショングループ
    カスタムのバリデーショングループを samples.ec01.bean.validator.group.JapaneseChecks に記述します。Beanクラスのアノテーションで利用されています。
    4 JavaBeanクラス
    samples.ec01.bean.UserBean でカスタムのバリデーションとバリデーショングループを利用しています。
  • バリデーションエラーメッセージを定義する
    Bean Validationエラーメッセージはプロパティファイルに定義し、多言語利用が可能です。

  • コマンドクラスでBean Validationを利用する

    ファイル名

    /src/main/java/samples/ec01/command/inquiry/RegistInquiryCommand.java

    ......
    @ActionMapping(
            name = "samples/ec01/inquiry/doInquiry",
            displayName = "お問合せ登録",
            privileged = true,
            tokenCheck = @TokenCheck(
                    executeCheck = true,
                    consume = true,
                    exceptionRollback = true),
            result = {
                    @Result(
                            exception = MappingException.class,  (1)
                            type = Type.TEMPLATE,
                            value = "samples/ec01/inquiry/inquiry"),
                    @Result(
                            status = Constants.CMD_EXEC_SUCCESS,
                            type = Type.TEMPLATE,
                            value = "samples/ec01/inquiry/inquirySuccess")})
    @CommandClass(
            name = "samples/ec01/inquiry/RegistInquiryCommand",
            displayName = "お問合せ登録コマンド")
    public class RegistInquiryCommand implements Command {
    
        private final BeanParamMapper mapper = new BeanParamMapper().withValidation()
                .whitelistPropertyNameRegex("^(mail|content|familyName(Kana)?|firstName(Kana)?)$"); (2)
        public static final String RESULT_INQUIRY_BEAN = "inquiryBean";
    
    
        @Override
        public String execute(RequestContext request) {
            // 入力チェック
            InquiryBean inquiryBean = new InquiryBean();
            request.setAttribute(RESULT_INQUIRY_BEAN, inquiryBean);
            // 日本語専用"name_kana"取得フォーム
            if (Consts.LANGUAGE_JA.equals(TemplateUtil.getLanguage()) || TemplateUtil.getLanguage() == null) {
                mapper.populate(inquiryBean, request.getParamMap(), Default.class, JapaneseChecks.class); (3)
            } else {
                mapper.populate(inquiryBean, request.getParamMap(), Default.class); (4)
            }
    
            Inquiry inquiry = inquiryBean.toEntity();
            // 問い合わせステータス
            // 1 : 未対応
            // 2 : 対応中
            // 3 : 対応完了
            // 4 : 終了
            SelectValue inquiryStatus = new SelectValue(InquiryStatus.NOT_DEAL.getValue());
            inquiry.setInquiryStatus(inquiryStatus);
            // 請求の登録
            EntityDaoHelper.insert(inquiry);
    
            return Constants.CMD_EXEC_SUCCESS;
        }
    }
    1 MappingExceptionが発生した場合の遷移先Templateを指定します。
    ※ Requestスコープに WebRequestConstants.EXCEPTION をキーにMappingExceptionが格納されます。
    2 Beanクラスに画面からの入力値をマッピングするためのユーティリティクラスを初期化します。
    ※ whitelistPropertyNameRegexメソッドにセット可能な項目の正規表現式を指定します。
    3 多言語利用で「日本語」が選択されている、または多言語利用の設定が取得できなかった場合、samples.ec01.bean.validator.group.JapaneseChecks グループとデフォルトグループに属する項目に対してバリデーションが実行されます。
    ※ populateメソッドはスレッドセーフですが、それ以外の delimitersなどの設定用メソッドはスレッドセーフではありません。 詳しい説明は、 org.iplass.mtp.command.beanmapper.BeanParamMapper のJavaDocを参照してください。
    4 多言語利用で「日本語」以外が選択されている場合、デフォルトグループに属する項目のみに対してバリデーションが実行されます。
  • JSPテンプレートファイル

    ファイル名

    /jsp/samples/ec01/inquiry/registInquiry.jsp

    ----------------------------------------以上略----------------------------------------
            <m:bind bean="${inquiryBean}"> (1)
            <form class="custom-form mt-3" action="${m:tcPath()}/samples/ec01/inquiry/doInquiry" method="post">
                <input type="hidden" name="_t" value="${m:token()}">
                <div class="form-group row">
                    ......
                    <div class="col-12 col-md-6 mt-3">
                        <div>
                            <m:bind prop="familyNameKana"> (2)
                                <label for="${name}" class="col-form-label label-hidden">${m:rs('iplass-wtp-messages', 'samples.ec01.inquiry.regist.familyNameKana')}</label>
                                <input type="text" class="form-control border rounded input-hint-visible" name="${name}" value="${value}" placeholder="${m:rs('iplass-wtp-messages', 'samples.ec01.inquiry.regist.familyNameKana')}"> (3)
                                <small class="form-text text-danger"><m:errors /></small> (4)
                            </m:bind>
                        </div>
                    </div>
                    ......
            </form>
            </m:bind>
    ----------------------------------------以下略----------------------------------------
    1 PageContext にBeanインスタンスをバインドします。
    2 PageContext にBeanインスタンスに格納されているプロパティ名と値をバインドします。 autoDetectErrors=true(デフォルトがtrue) の場合、 WebRequestConstants.EXCEPTION をキーにMappingExceptionを取得し、MappingResultのインスタンスが自動解決されます。当該Bean、プロパティに紐付くエラーがバインドされます。
    3 バインドされたプロパティの名前と値をテキストボックスにバインドします。
    4 バインドされたエラーメッセージを画面に出力します。

    ※ 詳しい設定方法については、 org.iplass.mtp.web.template.tags.BindTagorg.iplass.mtp.web.template.tags.ErrorsTag のJavaDocを参照してください。

  • 動作確認

    • 「姓」と「名」を空文字として登録しようとした場合、バリデーションエラーが発生することを画面から確認できます。

    • 「セイ」と「メイ」に全角カタカナ以外の値を入れて登録しようとした場合、バリデーションエラーが発生することを画面から確認できます。

      sample ec java jsp bean validation error

    • 多言語利用で「英語」が選択された場合、英語のバリデーションエラーメッセージが表示されることを確認できます。

      sample ec java jsp bean validation error en

      ※ 英語用の画面には、カタカナの「セイ」と「メイ」の入力項目がないため、日本語用の画面と比べてレイアウトに少し違いがあります。

3.3. Entity作成

  • Admin ConsoleのEntity定義で Mapping Class 機能を利用することで、Entity定義に合ったJavaクラスを自動生成することができます。

    パッケージ

    samples.ec01.entity

  • Entityの多言語設定をします。
    Admin Console部分の設定でEntity多言語対応を参照してください。

3.4. ErrorUrlSelector

エラー画面Template制御スクリプトです。

  • トークンエラーが発生した場合を例として説明していきます。

    ファイル名

    src/main/java/samples/ec01/web/EcErrorUrlSelector.java

    public class EcErrorUrlSelector extends GemErrorUrlSelector {
    
        private final String ROOT_PATH = "samples/ec01";
        private final String TEMPURL_TOKEN_ERROR = ROOT_PATH + "/error/tokenError";
        private final String TEMPURL_ENTITY_ERROR = ROOT_PATH + "/error/entityError";
        private final String TEMPURL_USER_EXISTS_ERROR = ROOT_PATH + "/error/userExistsError";
        private final String TEMPURL_SESSION_VALUE_NOT_FOUND_ERROR = ROOT_PATH + "/error/sessionValueNotFoundError";
        private final String TEMPURL_SYSTEM_ERROR = ROOT_PATH + "/error/systemError";
    
        @Override
        public String getErrorTemplateName(Throwable exception, RequestContext request, String path) {
            Exception error = (Exception) request.getAttribute(WebRequestConstants.EXCEPTION);
            // ECサイト用
            if (path != null && path.startsWith(ROOT_PATH)) {
                // TokenValidationException用
                if (error instanceof TokenValidationException) {
                    return TEMPURL_TOKEN_ERROR; (1)
                    // EntityValidationException用
                } else if (error instanceof EntityValidationException) {
                    return TEMPURL_ENTITY_ERROR;
                    // UserExistsException
                } else if (error instanceof UserExistsException) {
                    return TEMPURL_USER_EXISTS_ERROR;
                    // SessionValueNotFoundException
                } else if (error instanceof SessionValueNotFoundException) {
                    return TEMPURL_SESSION_VALUE_NOT_FOUND_ERROR;
                    // その他のエラー用
                } else {
                    return TEMPURL_SYSTEM_ERROR;
                }
            }
            return super.getErrorTemplateName(exception, request, path);
        }
    }
    1 TokenValidationExceptionが発生した場合、カスタムの samples/ec01/error/tokenError テンプレートが呼び出されます。
  • カスタムのErrorUrlSelectorの実装クラスを mtp-service-config.xml に登録する必要があります。設定ファイルを参照ください。

  • メタデータ定義ファイル

    ファイル名

    samples-ec01-ce-metadata.xml

    <contextPath name="/template">
    ----------------------------------------以上略----------------------------------------
        <!-- エラー画面 -->
        <metaDataEntry>
            <metaData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xsi:type="metaJspTemplate">
                <name>samples/ec01/error/tokenError</name> (1)
                <displayName>トークンエラー画面</displayName>
                <path>/jsp/samples/ec01/error/genericError.jsp</path> (2)
                <layoutId>/action/samples/ec01/layout/defaultLayout</layoutId>
                <contentType>text/html; charset=utf-8</contentType>
            </metaData>
        </metaDataEntry>
    ----------------------------------------以下略----------------------------------------
    1 トークンエラー画面のテンプレート名
    2 エラーテンプレートファイルを指定
  • 共通エラーテンプレートファイル

    ファイル名

    /src/main/webapp/jsp/samples/ec01/error/genericError.jsp

  • 動作確認

    • TokenValidationExceptionが発生した場合、カスタムのテンプレートが表示されること。

      コンソールに出力されたエラーログは以下の通りです。

      org.iplass.mtp.web.actionmapping.TokenValidationException: 不正な画面遷移が発生しました(一連の登録処理中にブラウザの戻るボタン等を押下してしまいますと正常に処理を継続できない場合があります)。
          at org.iplass.mtp.impl.web.interceptors.TokenInterceptor.doError(TokenInterceptor.java:84)
          at org.iplass.mtp.impl.web.interceptors.TokenInterceptor.intercept(TokenInterceptor.java:114)
          at org.iplass.mtp.impl.command.InvocationImpl.proceedCommand(InvocationImpl.java:115)
          at org.iplass.mtp.impl.web.actionmapping.WebInvocationImpl.proceedCommand(WebInvocationImpl.java:171)
          at org.iplass.mtp.impl.command.interceptors.TransactionInterceptor.lambda$intercept$0(TransactionInterceptor.java:34)
          at org.iplass.mtp.transaction.TransactionManager.doTransaction(TransactionManager.java:114)
          at org.iplass.mtp.transaction.Transaction.with(Transaction.java:303)
          at org.iplass.mtp.impl.command.interceptors.TransactionInterceptor.intercept(TransactionInterceptor.java:33)
    • エラー内容表示

      sample ec java jsp errorselector token error

3.5. ReportOutput(注文明細ダウンロード)

  • POIを用いてExcel形式の注文明細帳票の出力機能を実装しています。

  • Java/JSP版では、Javaクラスを用いてTemplateの「Output Logic」を実装しています。

    ファイル名

    samples.ec01.template.report.OrderOutputLogic

  • 帳票テンプレート
    作成方法は、開発者ガイドの帳票出力(Jasper/JXLS/POI)の章を参照ください。

  • POI帳票出力機能の動作確認

    • 管理画面で注文検索一覧画面を開き、「詳細」リンクをクリックします。

      sample ec java jsp report order list

    • 「注文情報ダウンロード」ボタンをクリックします。

      sample ec java jsp report download

    • ダウンロードしたExcel帳票を確認します。
      サンプルアプリでは、英語用の帳票テンプレートも別途用意しています。

      sample ec java jsp report download file

3.6. Buildin EL関数

  • iPLAssのJSPタグライブラリに定義されているビルトインのEL関数を利用しています。

    <%@ taglib prefix="m" uri="http://iplass.org/tags/mtp"%> (1)
    ----------------------------------------以上略----------------------------------------
    <div class="row">
        <div class="col-12">
            <div class="border-top"></div>
            <nav class="breadcrumb all-breadcrumb">
                <a class="breadcrumb-item text-primary" href="${m:tcPath()}/samples/ec01/top"> (2)
                    ${m:rs('iplass-wtp-messages', 'samples.ec01.all.breadcrumb.home')} (3)
                </a>
                <span class="breadcrumb-item active">
                    ${m:rs('iplass-wtp-messages', 'samples.ec01.inquiry.regist.title')}
                </span>
            </nav>
        </div>
        <div class="col-12">
            <span class="h4">${m:rs('iplass-wtp-messages', 'samples.ec01.inquiry.regist.title')}</span>
            <m:bind bean="${inquiryBean}">
            <form class="custom-form mt-3" action="${m:tcPath()}/samples/ec01/inquiry/doInquiry" method="post">
                <input type="hidden" name="_t" value="${m:token()}"> (4)
                <div class="form-group row">
                    <div class="col-12 col-md-6 mt-3">
                        <div>
                            <m:bind prop="familyName">
                                 <label for="${name}" class="col-form-label label-hidden">${m:rs('iplass-wtp-messages', 'samples.ec01.inquiry.regist.familyName')}</label>
                                 <input type="text" class="form-control border rounded input-hint-visible" name="${name}" value="${value}" placeholder="${m:rs('iplass-wtp-messages', 'samples.ec01.inquiry.regist.familyName')}">
                                 <small class="form-text text-danger"><m:errors /></small>
                            </m:bind>
                        </div>
                    </div>
    ----------------------------------------以下略----------------------------------------
    1 iPLAssのJSPタグライブラリ
    2 tcPath(): テナント名まで含むコンテキストパスを取得します。
    3 rs(): 指定された基底名とキーからResourceBundleに定義された文字列を返します。多言語メッセージを併せて利用できます。
    4 token(): トランザクショントークンを出力します。

    ※ 他のEL関数の使い方については、org.iplass.mtp.web.template.ELFunctions のJavaDocを参照してください。

3.7. WebApiとの連携

Ajaxを利用することで、WebApiで連携することができます。一般消費者向けのECサイト画面における全文検索処理を例として説明していきます。

  • 開発者ガイドのWebApiの作成方法を参照してください。
    以下はここで利用しているWebApiです。

    WebApi名

    samples/ec01/search/fulltextSearch

  • WebApiを利用しているJSPテンプレート

    ファイル名

    /src/main/webapp/jsp/samples/ec01/search/search.jsp

    ----------------------------------------JSP部分略----------------------------------------
    <script type="text/javascript">
    function fullTextSearch() {
        var productName = $("#productName").val();
        var categoryOid = $("#categoryList").attr("category-item-selected");
        if(productName == "") {
            $("#helpId").html("${m:rs('iplass-wtp-messages', 'samples.ec01.search.nokeyword')}");
            return false;
        }
        var param = "{\"productName\":\"" + productName + "\",\"categoryOid\":\"" + categoryOid +"\"}";
        $.ajax({
            type: "POST",
            contentType: "application/json",
            url:"${m:tcPath()}/api/samples/ec01/search/fulltextSearch", (1)
            dataType: "json",
            data: param,
            success: function(commandResult){
                if (commandResult.exceptionType != null) { (2)
                    alert("${m:rs('iplass-wtp-messages', 'samples.ec01.search.jsError')}"+ commandResult.exceptionType +"\\n"+commandResult.exceptionMessage);
                    return;
                }
                if(commandResult.status == "SUCCESS"){
                    if(commandResult.defaultResult != null && commandResult.defaultResult.length > 0){
                        var resultHtml = ListSearchResult(commandResult.defaultResult, productName); (3)
                        $("#searchResultDiv").html(resultHtml);
                    }
                    else{
                        $("#helpId").html("${m:rs('iplass-wtp-messages', 'samples.ec01.search.keyword')}: " + productName + ", " + "${m:rs('iplass-wtp-messages', 'samples.ec01.search.noResult')}");
                    }
                }
            }
        });
    }
    function dropdownSelect(item){
        var t = $(item);
        var v = t.attr("category-item-value");
        $("#categoryList").text(t.html()).attr("category-item-selected", v);
    }
    function ListSearchResult(entities, productName){ (4)
        var yen = "${m:rs('iplass-wtp-messages', 'samples.ec01.all.yen')}";
        var html =  "<div class=\"col-12 mb-2\">";
            html += "   <h4>${m:rs('iplass-wtp-messages', 'samples.ec01.search.result')}" + productName + "</h4>";
            html += "</div>";
        for(var i =0; i < entities.length; i++){
            var name = entities[i].name;
            var price = isNaN(entities[i].price)? "" : entities[i].price;
            var imageUrl = "${m:tcPath()}/samples/ec01/resource/bin?id=" + entities[i].productImg.lobId + "&type=${Consts.BIN_TYPE_PRODUCT_IMG}";
            var detailUrl = "${m:tcPath()}/samples/ec01/product/detail?productId=" + entities[i].oid;
            html += "<div class=\"col-12 col-md-4\">";
            html += "   <div class=\"card border-light border-0\">";
            html += "       <a href=\"" + detailUrl + "\" class=\"h-100\">";
            html += "          <img class=\"card-img-top img-thumbnail img-fluid all-product-img\" src=" + imageUrl + " alt=\"" + name + "\">";
            html += "       </a>";
            html += "       <div class=\"card-body pt-md-1 text-center\">";
            html += "          <div>";
            html += "              <a href=\""+ detailUrl +"\" class=\"card-link text-dark\">" + name + "</a>";
            html += "           </div>";
            html += "           <div class=\"all-price\">";
            html += "              <span>" + price + "</span>" + yen;
            html += "           </div>";
            html += "       </div>";
            html += "   </div>";
            html += "</div>";
        }
        return html;
    }
    </script>
    1 WebApiによる検索処理を呼び出します。
    2 検索処理でエラーが発生した場合、クライアント側での処理。
    3 返された検索処理の結果を取得し、クライアント側の描画処理を呼び出します。
    4 検索結果の描画処理。
  • 動作確認

    • キーワードを入力し、検索ボタンをクリックします。

      sample ec java jsp webapi fulltext search

    • 返却値の例

      {"status":"SUCCESS","defaultResult":[{"definitionName":"samples.ec01.products.Product","price":2709,"name":"Javaルールブック ~読みやすく効率的なコードの原則","productImg":{"lobId":195,"name":"wolf.png","type":"image/png","definitionName":"samples.ec01.products.Product","propertyName":"productImg","oid":"EC011","size":13872},"oid":"EC011"},{"definitionName":"samples.ec01.products.Product","price":2300,"name":"超図解 Javaルールブック (超図解シリーズ) [単行本]","productImg":{"lobId":208,"name":"bear.png","type":"image/png","definitionName":"samples.ec01.products.Product","propertyName":"productImg","oid":"EC019","size":12051},"oid":"EC019"}]}
    • 検索結果を画面から確認できます。

      sample ec java jsp webapi fulltext search result

3.8. セキュリティ対策

対象とする機能

オレンジ色の部分を例にセキュリティ対策を解説していきます。

sample ec fullcustomize flow2
セキュリティ対策について

ここでは会員登録を例としてiPLAssで利用できる以下のセキュリティ対策について説明します。

・ XSS対策となるエスケープ機能 : ユーザーの入力内容を正常に画面表示させる
・ CSRF対策/トランザクション重複起動対策となるトークンチェック機能 : 画面表示時に正常な画面遷移が行われているかをチェックする

会員登録処理の中でそれぞれの機能は下記のように利用されます。

  • エスケープの導入

Templateの作成

入力された値を出力する会員情報確認画面にて、該当箇所に ${m:esc()} エスケープを導入します。

表示名 Template名

会員情報確認画面

samples/ec01/member/confirmMemberInfo

<%@ taglib prefix="m" uri="http://iplass.org/tags/mtp"%> (1)
----------------------------------------以上略----------------------------------------
        <div class="card col-12 bg-light">
            <div class="card-body">
                <div class="row mt-3 border-bottom">
                    <div class="col-12 col-md-4">
                        <span class="text-muted fw-bold">${m:rs('iplass-wtp-messages', 'samples.ec01.member.regist.userId')}</span>
                    </div>
                    <div class="col-12 col-md-8">${m:esc(userBean.userId)}</div>
                </div>
                <div class="row mt-3 border-bottom">
                    <div class="col-12 col-md-4">
                        <span class="text-muted  fw-bold">${m:rs('iplass-wtp-messages', 'samples.ec01.member.registConfirm.fullName')}</span>
                    </div>
                    <div class="col-12 col-md-4">
                        <span class="text-muted  fw-bold">${m:rs('iplass-wtp-messages', 'samples.ec01.member.regist.familyName')}</span>
                        &nbsp;${m:esc(userBean.familyName)} (2)
                    </div>
                    <div class="col-12 col-md-4">
                        <span class="text-muted  fw-bold">${m:rs('iplass-wtp-messages', 'samples.ec01.member.regist.firstName')}</span>
                        &nbsp;${m:esc(userBean.firstName)} (2)
                    </div>
                </div>
                <% if (Consts.LANGUAGE_JA.equals(TemplateUtil.getLanguage()) || TemplateUtil.getLanguage() == null) { %>
                <div class="row mt-3 border-bottom">
                    <div class="col-12 col-md-4">
                        <span class="text-muted  fw-bold">${m:rs('iplass-wtp-messages', 'samples.ec01.member.registConfirm.fullNameKana')}</span>
                    </div>
                    <div class="col-12 col-md-4">
                        <span class="text-muted  fw-bold">${m:rs('iplass-wtp-messages', 'samples.ec01.member.regist.familyNameKana')}</span>
                        &nbsp;${m:esc(userBean.familyNameKana)} (2)
                    </div>
                    <div class="col-12 col-md-4">
                        <span class="text-muted  fw-bold">${m:rs('iplass-wtp-messages', 'samples.ec01.member.regist.firstNameKana')}</span>
                        &nbsp;${m:esc(userBean.firstNameKana)} (2)
                    </div>
                </div>
                <% } %>
                <div class="row mt-3 border-bottom">
                    <div class="col-12 col-md-4">
                        <span class="text-muted  fw-bold">${m:rs('iplass-wtp-messages', 'samples.ec01.member.regist.mail')}</span>
                    </div>
                    <div class="col-12 col-md-8">${m:esc(userBean.mail)}</div> (2)
                </div>
            </div>
        </div>
----------------------------------------以下略----------------------------------------
1 iPLAssのJSPタグライブラリ
2 今回は出力先がHTML形式であるためすべて ${m:esc(変数名)} の形式でエスケープを行っています。
  • トークンチェックの導入
    この機能では、iPLAssで実装されている正常に画面遷移してきたことを証明するCSRFトークンを利用します。不正な画面遷移を禁止するActionでトークンをチェックすることにより、正常な画面遷移が行われたかを判断します。

    • Actionの設定
      不正な画面遷移を禁止するActionでトークンをチェックする設定を行います。

      表示名 Action名

      会員情報確認アクション

      samples/ec01/member/confirmMemberInfo

      @ActionMapping(
              name = "samples/ec01/member/confirmMemberInfo",
              displayName = "会員情報確認アクション",
              privileged = true,
              tokenCheck = @TokenCheck( (1)
                      executeCheck = true,
                      consume = true,
                      exceptionRollback = true),
              result = {
                      @Result(
                              status = Constants.CMD_EXEC_ERROR,
                              type = Type.TEMPLATE,
                              value = "samples/ec01/member/inputMemberInfo"),
                      @Result(
                              status = Constants.CMD_EXEC_SUCCESS,
                              type = Type.TEMPLATE,
                              value = "samples/ec01/member/confirmMemberInfo") })
      @CommandClass(
              name = "samples/ec01/member/ConfirmMemberInfoCommand",
              displayName = "会員情報確認コマンド")
      public class ConfirmMemberInfoCommand implements Command {
      ----------------------------------------以下略----------------------------------------
3 ActionMapping定義にTokenCheckのアノテーションを利用してトークンチェックを行う設定を追加します。

以下の設定が可能です。

executeCheck

トークンチェックを行うかどうか

useFixedToken

セッション単位に固定に払いだされるトークンを利用するか

consume

トークンを消費するか

exceptionRollback

Exception発生時にトークンをロールバックするか

この設定により直接この画面へ遷移するとエラーページが表示されます。

sample ec java jsp security token error

  • Templateでトークンを作成して埋め込む
    不正な画面遷移を禁止するActionへ遷移する画面でトークンを作成して埋め込みます。

    表示名 Template名

    会員情報入力画面

    samples/ec01/member/inputMemberInfo

    ----------------------------------------以上略----------------------------------------
    <%@ taglib prefix="m" uri="http://iplass.org/tags/mtp"%>
    <div class="row">
        <div class="col-12">
            <div class="border-top"></div>
            <nav class="breadcrumb all-breadcrumb">
                <a class="breadcrumb-item text-primary" href="${m:tcPath()}/samples/ec01/top">
                    ${m:rs('iplass-wtp-messages', 'samples.ec01.all.breadcrumb.home')}
                </a>
                <span class="breadcrumb-item active">
                    ${m:rs('iplass-wtp-messages', 'samples.ec01.member.regist.title')}
                </span>
            </nav>
        </div>
        <div class="col-12">
            <span class="h4">${m:rs('iplass-wtp-messages', 'samples.ec01.member.regist.title')}</span>
            <form class="custom-form mt-3" action="${m:tcPath()}/samples/ec01/member/confirmMemberInfo" method="post">
            <input type="hidden" name="_t" value="${m:token()}"> (1)
            <m:bind bean="${userBean}" mappingResult="${result}">
                <div class="form-group row">
                    <div class="col-12">
                        <div>
                            <m:bind prop="userId">
                                <label for="${name}" class="col-form-label label-hidden">
                                    ${m:rs('iplass-wtp-messages', 'samples.ec01.member.regist.userId')}
                                </label>
                                <input type="text" class="form-control border rounded input-hint-visible" name="${name}" value="${value}" placeholder="${m:rs('iplass-wtp-messages', 'samples.ec01.member.regist.userId')}">
                                <small class="form-text text-danger"><m:errors/></small>
                            </m:bind>
                        </div
    ----------------------------------------以下略----------------------------------------
4 EL関数を利用してトークンを生成します。

3.9. 多言語対応

多言語を利用するために、サンプルアプリでは以下の対応を行っています。

4. 設定ファイル

4.1. service-config

ファイル名

/src/main/resources/mtp-service-config.xml

  • カスタムのErrorUrlSelectorの登録

        <!-- Web App Settings -->
        <service>
            <interface>org.iplass.mtp.impl.web.WebFrontendService</interface>
    
            <!-- ■ your error url selector ■ -->
            <property name="errorUrlSelector" class="samples.ec01.web.EcErrorUrlSelector" /> (1)
        </service>
    1 カスタムのErrorUrlSelectorを登録しています。
  • メタデータ定義の登録

        <!-- XmlResource MetaData and Annotation MetaData Settings -->
        <service>
            <interface>org.iplass.mtp.impl.metadata.MetaDataRepository</interface>
    
            <!-- ■ your app metadata xml file name (additional="true) ■ -->
            <property name="resourcePath" value="/samples-ec01-ce-metadata.xml" additional="true" /> (1)
            <!-- ■ your app command list class (additional="true) ■ -->
            <property name="annotatedClass" value="samples.ec01.command.metadata.CommandList" additional="true"/> (2)
    
        </service>
    1 メタデータの定義ファイル
    2 アノテーションでコマンドのメタデータ定義を作っています。
  • 全文検索機能

        <!-- Fulltext Search Service Settings -->
        <service>
            <interface>org.iplass.mtp.impl.fulltextsearch.FulltextSearchService</interface>
            <property name="useFulltextSearch" value="true" /> (1)
            <property name="maxRows" value="1000" />
            <property name="throwExceptionWhenOverLimit" value="true"/>
    
            <!-- lucene利用 -->
            <class>org.iplass.mtp.impl.fulltextsearch.lucene.LuceneFulltextSearchService</class>
            <property name="directory" value="[set your lucene index file store path. eg: D:\tmp\lucene]" /> (2)
            <property name="analyzer" value="org.apache.lucene.analysis.ja.JapaneseAnalyzer" />
            <property name="indexWriterRAMBufferSizeMB" value="64.0"/>
            <property name="redundantTimeMinutes" value="10"/>
        </service>
    1 全文検索機能を有効化しています。
    2 全文検索のINDEXファイルの作成場所を指定してください。

5. リソースファイル

5.1. メタデータ定義

  • コマンドのメタデータ定義

    ファイル名

    /src/main/java/samples/ec01/command/metadata/CommandList.java

  • 他のメタデータ定義

    ファイル名

    /src/main/resources/samples-ec01-ce-metadata.xml

    ここでは2種類のメタデータが用意されています。

    metaDataList
        ┣ contextPath (name=/entity) (1)
        ┣ contextPath (name=/property/select) (1)
        ┣ contextPath (name=/template) ※ 帳票出力機能と管理トップ画面 (1)
        ┣ contextPath (name=/view/calendar) (1)
        ┣ contextPath (name=/view/generic) (1)
        ┣ contextPath (name=/view/menu/item) (1)
        ┣ contextPath (name=/view/menu/tree) (1)
        ┣ contextPath (name=/view/top) (1)
        ┣ contextPath (name=/view/treeview) (1)
        ┣ contextPath (name=/view/filter) (1)
        ┗ contextPath (name=/template) (2)
    1 Admin Consoleで作成したメタデータ定義です。Packaging機能もしくはMetaDataExplorer機能を利用することでエクスポートしたものです。
    2 Templateのメタデータ定義は手動で作成しています。
    ※ 帳票出力機能と管理トップ画面のTemplate定義はAdmin Consoleで作成し、エクスポートしています。

    手動で作成したTemplate定義の例。

    ----------------------------------------以上略----------------------------------------
    <contextPath name="/template">
        <!-- エラー画面 -->
        <metaDataEntry>
            <metaData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xsi:type="metaJspTemplate">
                <name>samples/ec01/error/loginError</name>
                <displayName>認証エラー画面</displayName>
                <path>/jsp/samples/ec01/error/genericError.jsp</path>
                <layoutId>/action/samples/ec01/layout/defaultLayout</layoutId>
                <contentType>text/html; charset=utf-8</contentType>
            </metaData>
        </metaDataEntry>
    ----------------------------------------以下略----------------------------------------

5.2. メッセージファイル

  • JSPテンプレートで特定のResourceBundleに定義された文字列を取得することができ、言語別にプロパティファイルを作成することで多言語利用が可能です。

    ファイル名

    iplass-wtp-messages_ja.properties

    samples.ec01.all.breadcrumb.home                = ホーム
    samples.ec01.all.pagination.next                = 次へ
    samples.ec01.all.pagination.prev                = 前へ
    samples.ec01.all.yen                            = 円
    samples.ec01.backoffice.stockUpdate.doUpdate    = 一括更新
    samples.ec01.backoffice.stockUpdate.product     = 商品名
    samples.ec01.backoffice.stockUpdate.stock       = 在庫数
    samples.ec01.backoffice.stockUpdate.title       = 在庫一括更新
    samples.ec01.cart.info.checkOut                 = お会計
    samples.ec01.cart.info.emptyMsg.p1              = カートが空になっています。
    ----------------------------------------以下略----------------------------------------

    ファイル名

    iplass-wtp-messages_en.properties

    samples.ec01.all.breadcrumb.home                = Home
    samples.ec01.all.pagination.next                = Next
    samples.ec01.all.pagination.prev                = Prev
    samples.ec01.all.yen                            = Yen
    samples.ec01.backoffice.stockUpdate.doUpdate    = Bulk update
    samples.ec01.backoffice.stockUpdate.product     = Product name
    samples.ec01.backoffice.stockUpdate.stock       = Stock
    samples.ec01.backoffice.stockUpdate.title       = Stock bulk update
    samples.ec01.cart.info.checkOut                 = Check out
    samples.ec01.cart.info.emptyMsg.p1              = Your cart is currently empty.
    ----------------------------------------以下略----------------------------------------

5.3. Bean Validationエラーメッセージ

  • 言語別にプロパティファイルを作成することで多言語利用が可能です。

    ファイル名

    /src/main/resources/ValidationMessages_ja.properties

    samples.ec01.bean.validation.Tel.invalidChar    = 「数字」および「-」のみ利用可能です。(1)
    samples.ec01.bean.validation.UserId.invalidChar = 「英数字」および「-」(ハイフン)「@」「_」「.」(ピリオド)のみ利用可能です。
    samples.ec01.bean.validation.UserId.outOfLength = ユーザーIDは{min}文字以上{max}文字以下です (2)
    samples.ec01.bean.validation.isBlank            = 値を入力してください。
    samples.ec01.bean.validation.notKana            = 全角カタカナを入力してください。
    ......

    ファイル名

    /src/main/resources/ValidationMessages_en.properties

    samples.ec01.bean.validation.Tel.invalidChar    = Please enter alphanumeric characters or "-"(hypen) . (1)
    samples.ec01.bean.validation.UserId.invalidChar = Please enter alphanumeric characters or "-"(hypen), "@", "_"(underscore), "."(dot) .
    samples.ec01.bean.validation.UserId.outOfLength = User ID must be in range between {min} and {max} characters. (2)
    samples.ec01.bean.validation.isBlank            = Please enter value.
    samples.ec01.bean.validation.notKana            = Please enter Katakana.
    ......
    1 多言語を利用するので、日本語と英語のバリデーションエラーメッセージを用意しています。
    2 メッセージにパラメーターの利用が可能です。

6. テストコード

  • プロジェクトの src/test/ フォルダを開くと、以下の構成になっています。

    src.test
        ┣ java
        ┃   ┗ samples.ec01.test.command (1)
        ┃       ┣ inquiry
        ┃       ┃   ┗ RegistInquiryCommandTest.java
        ┃       ┗ TopCommandTest.java
        ┗ resources (2)
            ┣ mtptest.properties
            ┗ test-mtp-service-config.xml
    1 テストクラス
    2 テストクラス実行用の設定ファイル
  • テストクラス

    パッケージ クラス名

    samples.ec01.test.command

    TopCommand.java

    samples.ec01.test.command.inquiry

    RegistInquiryCommandTest.java

  • テスト実行用の設定ファイル

    ファイル名

    /src/test/resources/mtptest.properties

    configFileName=/test-mtp-service-config.xml (1)
    rollbackTransaction=true (2)
    tenantName= (3)
    userId= (4)
    password= (5)
    1 テスト実行用のデータベース接続とメタデータ定義が記述されたファイル
    2 トランザクションロールバックの設定
    3 テストを実行するテナント
    4 テストを実行するユーザー
    5 テストを実行するユーザーのパスワード

    ※ プロパティによる指定以外に、クラスレベルアノテーションとメソッドレベルアノテーションによる指定も可能です。詳しい設定方法については、 org.iplass.mtp.test.MTPJUnitTestRule のJavaDocを参照ください。

    ファイル名

    /src/test/resources/test-mtp-service-config.xml

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <!DOCTYPE serviceDefinition>
    <serviceDefinition>
        <!-- If use oracle, inherits mtp-service-config-mysql.xml for convenience. -->
    
        <!-- <inherits>/mtp-core-service-config-oracle.xml</inherits> -->
        <inherits>/mtp-web-service-config.xml</inherits>
        <inherits>/gem-service-config.xml</inherits>
    
        <inherits>/mtp-core-service-config-mysql.xml</inherits>
    
        <!-- Rdb Connection Settings -->
        <service>
            <interface>org.iplass.mtp.impl.rdb.connection.ConnectionFactory</interface>
            <class>org.iplass.mtp.impl.rdb.connection.DriverManagerConnectionFactory</class>
            <property name="url" value="jdbc:mysql://[host]:[port]/[schema]" /> (1)
            <property name="user" value="[user]" /> (2)
            <property name="password" value="[password]" /> (3)
            <property name="driver" value="com.mysql.cj.jdbc.Driver" />
        </service>
    
        <!-- XmlResource MetaData and Annotation MetaData Settings -->
        <service>
            <interface>org.iplass.mtp.impl.metadata.MetaDataRepository</interface>
            <property name="resourcePath" value="/samples-ec01-ce-metadata.xml" additional="true" /> (4)
            <property name="annotatedClass" value="samples.ec01.command.metadata.CommandList" additional="true"/> (5)
        </service>
    
    </serviceDefinition>
    1 テスト実行用のデータベース接続
    2 データベース接続ユーザー
    3 データベース接続ユーザーのパスワード
    4 メタデータの定義ファイル
    5 コマンドのメタデータ定義
  • 動作確認

    • Gradleでテストコードを実行する場合、プロジェクトのルートパスで以下のコマンドを実行してください。

      gradlew test
    • 実行結果

      :compileJava UP-TO-DATE
      :processResources UP-TO-DATE
      :classes UP-TO-DATE
      :compileTestJava UP-TO-DATE
      :processTestResources UP-TO-DATE
      :testClasses UP-TO-DATE
      :test UP-TO-DATE
      
      BUILD SUCCESSFUL
      
      Total time: 1.855 secs
    • Eclipseでテストコードを実行する場合、src.test.java パッケージを右クリックして Run as を選択し、JUnit Test を実行してください。