intra-mart Accel Platform アクセスコンテキスト 拡張プログラミングガイド 第2版 2015-12-01

3.1. アクセスコンテキストの実装例

この章では、アクセスコンテキスト、および、アクセスコンテキストのインスタンスを生成するためのコンテキストビルダを作成する方法を説明します。
アクセスコンテキスト、および、コンテキストビルダについての詳細は、「 アクセスコンテキスト仕様書 」-「 アクセスコンテキストフレームワーク 」を参照してください。

注意

この章で作成する実装例の動作確認は、intra-mart Accel Platform のサンプル機能を使用しているため、サンプルを含めて構築した環境で確認してください。

3.1.1. 機能定義と作業の流れ

この章で作成するアクセスコンテキストの要件は、以下の通りです。
  • Web実行環境で利用する。
  • ログインユーザの「ユーザ名」「メールアドレス」をそれぞれ文字列で保持する。
  • 任意のユーザでログイン後、アクセスコンテキストの内容を更新する。
アクセスコンテキストを作成して使用可能にするための作業手順は、以下の通りです。
順序 作業内容 解説
1 アクセスコンテキストクラスを実装する。 アクセスコンテキストの作成
2 コンテキストビルダクラスを実装する。 コンテキストビルダの作成
3 アクセスコンテキスト設定を用意する。 アクセスコンテキストの設定
4 アクセスコンテキストの動作を確認する。 アクセスコンテキストの動作確認

3.1.2. アクセスコンテキストの作成

以下の条件を満たすアクセスコンテキストを実装します。
  • ログインユーザの「ユーザ名」「メールアドレス」をそれぞれ文字列で保持する。
各情報を保持するため、アクセスコンテキストに持たせるプロパティを決定します。
今回の例では、「ユーザ名」「メールアドレス」の2つを保持するため、以下のように定義します。
プロパティ名 説明
userName
ユーザ名。IM共通マスタから取得する。
例) 青柳辰巳
mailAddress
メールアドレス。IM共通マスタのメールアドレス1を使用する。
例) aoyagi@example.com
次に、アクセスコンテキストクラスを作成します。
クラスを作成する場合は、以下のインタフェースを実装してください。
jp.co.intra_mart.foundation.context.model.Context
Context インタフェースを実装することで、getType メソッドの実装が必須となります。
完全修飾子(FQCN) sample.SimpleUserContext

package sample;

import jp.co.intra_mart.foundation.context.model.Context;

public class SimpleUserContext implements Context {

    /** バージョン番号(新規に採番してください) */
    private static final long serialVersionUID = 156377866768711512L;

    /** ユーザ名 */
    private String userName;

    /** メールアドレス */
    private String mailAddress;

    public String getMailAddress() {
        return mailAddress;
    }

    /**
     * コンテキスト種別(アクセスコンテキストの種類を表すインタフェースの型)を返却します。
     * @return このクラス自身のクラスオブジェクト
     */
    @SuppressWarnings("unchecked")
    @Override
    public Class<SimpleUserContext> getType() {
        return SimpleUserContext.class;
    }

    public String getUserName() {
        return userName;
    }

    public void setMailAddress(final String mailAddress) {
        this.mailAddress = mailAddress;
    }

    public void setUserName(final String userName) {
        this.userName = userName;
    }

}
実装が必要なメソッドとその説明は、以下の通りです。
  • getType メソッド

    自分自身のコンテキストのクラスタイプを返却してください。
    今回の例では、SimpleUserContext.class を返却します。

注意

Context インタフェースは Serializable インタフェースを継承しているため、serialVersionUID が必要です。
上記の値をそのまま使用せず、新しく採番してください。

3.1.3. コンテキストビルダの作成

次に、先ほど作成したアクセスコンテキストのインスタンスを生成するコンテキストビルダクラスを作成します。
クラスを作成する場合は、以下のクラスを継承してください。
jp.co.intra_mart.foundation.context.core.ContextBuilderSupport
ContextBuilderSupport クラスを継承することで、create メソッドの実装が必須となります。
完全修飾子(FQCN) sample.SimpleUserContextBuilder

package sample;

import java.util.Date;
import java.util.Locale;

import jp.co.intra_mart.common.platform.log.Logger;
import jp.co.intra_mart.foundation.context.Contexts;
import jp.co.intra_mart.foundation.context.core.ContextBuilderSupport;
import jp.co.intra_mart.foundation.context.core.Resource;
import jp.co.intra_mart.foundation.context.model.AccountContext;
import jp.co.intra_mart.foundation.context.model.Context;
import jp.co.intra_mart.foundation.exception.BizApiException;
import jp.co.intra_mart.foundation.i18n.datetime.DateTime;
import jp.co.intra_mart.foundation.i18n.timezone.SystemTimeZone;
import jp.co.intra_mart.foundation.master.user.UserManager;
import jp.co.intra_mart.foundation.master.user.model.User;
import jp.co.intra_mart.foundation.master.user.model.UserBizKey;

public class SimpleUserContextBuilder extends ContextBuilderSupport {

    private static final Logger LOGGER = Logger.getLogger(SimpleUserContextBuilder.class);

    /**
     * アクセスコンテキストのインスタンスを生成します。
     * @param resource 環境情報
     * @return アクセスコンテキストのインスタンス
     */
    @Override
    protected Context create(final Resource resource) {
        try {
            // ここに到達したことをログに出力
            LOGGER.info("SimpleUserContext created.");

            // アクセスコンテキストのインスタンスを生成して返却
            return createNewContext();
        } catch (final BizApiException e) {
            throw new RuntimeException(e);
        }
    }

    private SimpleUserContext createNewContext() throws BizApiException {
        // ログインユーザの情報をアカウントコンテキストから取得
        final AccountContext accountContext = Contexts.get(AccountContext.class);
        final String userCd = accountContext.getUserCd();
        final Locale locale = accountContext.getLocale();

        // ログインユーザの情報 (ユーザコード、ロケール) をキーとしてユーザ情報を取得
        final User user = getUser(userCd, locale);
        if (user == null) {
            // ユーザ情報が取得できないときは、空のアクセスコンテキストのインスタンスを返却
            return new SimpleUserContext();
        }

        // アクセスコンテキストのインスタンスに、ユーザ情報を設定
        final SimpleUserContext context = new SimpleUserContext();
        context.setUserName(user.getUserName());
        context.setMailAddress(user.getEmailAddress1());

        // アクセスコンテキストのインスタンスを返却
        return context;
    }

    private Date getBaseTime() {
        // ログインユーザのタイムゾーンで現在日付を取得
        final DateTime userDate = new DateTime(Contexts.get(AccountContext.class).getTimeZone());
        return new DateTime(SystemTimeZone.getDefaultTimeZone(), userDate.getYear(), userDate.getMonthOfYear(), userDate.getDayOfMonth()).getDate();
    }

    private User getUser(final String userCd, final Locale locale) throws BizApiException {
        // IM共通マスタの検索条件を設定
        final UserManager manager = new UserManager();
        final UserBizKey bizKey = new UserBizKey();
        bizKey.setUserCd(userCd);

        // IM共通マスタからユーザ情報を検索
        final User user = manager.getUser(bizKey, getBaseTime(), locale, false);
        return user;
    }

}
実装が必要なメソッドとその説明は、以下の通りです。
  • create メソッド

    自身のコンテキストビルダがサポートするアクセスコンテキストのインスタンスを返却してください。
    今回の例では、SimpleUserContext クラスのインスタンスを作成して、各プロパティ値を設定後、返却します。

    コラム

    Web実行環境のライフサイクル開始処理では、引数 Resource のリソース情報プロパティは設定されていないため、ここでは使用していません。
    実行環境によっては、プログラムの引数としてリソース情報が設定されているため、リソース情報を参照して処理をします。

3.1.4. アクセスコンテキストの設定

作成したアクセスコンテキストと、コンテキストビルダを紐付ける「アクセスコンテキスト設定」を用意します。
設定ファイルに、以下のような形式で記述してください。
パス WEB-INF/conf/context-config/{任意のファイル名}.xml

<?xml version="1.0"?>
<context-config
    xmlns="http://intra-mart.co.jp/foundation/context/context-config"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://intra-mart.co.jp/foundation/context/context-config ../../schema/context-config.xsd">

  <context
      name="sample.SimpleUserContext"
      depends="jp.co.intra_mart.foundation.context.model.AccountContext">

    <builder target="platform.request">
      <builder-class>sample.SimpleUserContextBuilder</builder-class>
    </builder>

  </context>

</context-config>

注意

ファイル名は、他のモジュールが提供しているものと重複しないようにするために、モジュールIDを接頭子にするなどの対策を行ってください。
例) sample-module_simple-user-context.xml
設定が必要なタグとその説明は、以下の通りです。
  • context タグ

    name 属性に、アクセスコンテキストクラスの完全修飾子(FQCN)を指定してください。
    今回の例では sample.SimpleUserContext を指定します。
    depends 属性に、依存するアクセスコンテキストクラスの完全修飾子(FQCN)を指定してください。
    今回の例では、SimpleUserContext 内で AccountContext を使用しているため、AccountContext が先に解決されるようにするために、依存関係を設定します。
  • builder タグ

    target 属性に、呼び出すタイミングを示すリソースIDを指定してください。
    今回の例では、Web実行環境の開始処理を表すリソースID platform.request を指定します。
    builder-class タグ内に、コンテキストビルダクラスの完全修飾子(FQCN)を指定します。
    今回の例では、sample.SimpleUserContextBuilder を指定します。
設定ファイルの詳細は、「 アクセスコンテキスト仕様書 」-「 アクセスコンテキスト設定 」を参照してください。

3.1.5. アクセスコンテキストの動作確認

作成したアクセスコンテキストが動作しているか、以下の手順で確認します。
  1. サーバ起動時のログを確認します。

    アクセスコンテキスト、コンテキストビルダ、および、設定ファイルが正しくアプリケーションサーバに配置されている場合、サーバ起動時に以下のログが出力されますので確認してください。
    [I.IWP.CONTEXT.MANAGER.10001] Used context. sample.SimpleUserContext
    
    実際の出力例
    [2014-05-01 12:00:00.000]  [resin-11]  INFO  jp.co.intra_mart.system.context.manager.impl.MultipleXmlContextConfiguration     5ib6n4szdhcs9     -  [I.IWP.CONTEXT.MANAGER.10001] Used context. jp.co.intra_mart.foundation.context.model.ClientContext
    [2014-05-01 12:00:00.000]  [resin-11]  INFO  jp.co.intra_mart.system.context.manager.impl.MultipleXmlContextConfiguration     5ib6n4szdhcsa     -  [I.IWP.CONTEXT.MANAGER.10001] Used context. jp.co.intra_mart.foundation.context.model.AccountContext
    [2014-05-01 12:00:00.000]  [resin-11]  INFO  jp.co.intra_mart.system.context.manager.impl.MultipleXmlContextConfiguration     5ib6n4szdhcsb     -  [I.IWP.CONTEXT.MANAGER.10001] Used context. jp.co.intra_mart.foundation.job_scheduler.JobSchedulerContext
    [2014-05-01 12:00:00.000]  [resin-11]  INFO  jp.co.intra_mart.system.context.manager.impl.MultipleXmlContextConfiguration     5ib6n4szdhcsc     -  [I.IWP.CONTEXT.MANAGER.10001] Used context. jp.co.intra_mart.foundation.user_context.model.UserContext
    [2014-05-01 12:00:00.000]  [resin-11]  INFO  jp.co.intra_mart.system.context.manager.impl.MultipleXmlContextConfiguration     5ib6n4szdhcsd     -  [I.IWP.CONTEXT.MANAGER.10001] Used context. jp.co.intra_mart.foundation.authz.context.AuthzSubjectContext
    [2014-05-01 12:00:00.000]  [resin-11]  INFO  jp.co.intra_mart.system.context.manager.impl.MultipleXmlContextConfiguration     5ib6n4szdhcse     -  [I.IWP.CONTEXT.MANAGER.10001] Used context. sample.SimpleUserContext
    [2014-05-01 12:00:00.000]  [resin-11]  INFO  jp.co.intra_mart.system.service.impl.ServiceControllerImpl     5ib6n4szdi8sf     -  [I.IWP.SERVICE.00009]   Initialize service "server.service.queue.management".
    [2014-05-01 12:00:00.000]  [resin-11]  INFO  jp.co.intra_mart.system.service.impl.ServiceControllerImpl     5ib6n4szdi8sg     -  [I.IWP.SERVICE.00009]   Initialize service "server.service.task.management".
    
  2. ログイン時に、ログ、および、アクセスコンテキストの保持内容を確認します。

    任意のユーザ(例:サンプルユーザの青柳)でログイン後、SimpleUserContextBuilder#create() メソッドの冒頭で実装しているログが以下のように出力されますので、システムログを確認してください。
    ログが出力されていれば、アクセスコンテキストの作成処理が正常に行われています。
    [] SimpleUserContext created.
    
    実際の出力例
    [2014-05-01 12:00:00.000]  [resin-port-8080-11] INFO  sample.SimpleUserContextBuilder    5ib6n4umb3mos     -  [] SimpleUserContext created.
    
    アクセスコンテキストの保持内容を確認するため、以下の URL にアクセスしてください。

    http://<HOST>:<PORT>/<CONTEXT_PATH>/sample/context/context_view.jsp

    「Context: sample.SimpleUserContext」カテゴリが表示され、各プロパティに想定通りの値が表示されていることを確認します。
    ../../_images/make_context_1.png
    図 アクセスコンテキストの内容