intra-mart Accel Platform ポートレット プログラミングガイド 第11版 2019-08-01

5. ポートレットの開発(JavaEE 開発編)

5.1. 概要

この章では、JavaEE 開発モデルを利用してポートレットの作成を行うための手順や注意事項を説明します。
ポートレットを作成するためには、「ポートレットのライフサイクル」の内容を理解し、どのライフサイクルを利用するのかを決定する必要があります。
  1. 画面開発 (render サイクル)

    ポートレットに表示する画面を作成します。モードやウィンドウステータスを判定して切り替えることも可能です。
    表示モード用の画面は必ず必要となります。
  2. アクション処理 (processAction サイクル)

    ポートレットからサブミットされたデータの処理を作成します。作成されたファンクションコンテナは、Action ハンドラと呼ばれ、ポートレット編集画面で登録することによって利用できます。
    また、Event を設定することによって、別のポートレットと連携することも可能です。
  3. イベント処理 (processEvent サイクル)

    他のポートレットから発生したイベントの受信処理を作成します。作成されたファンクションコンテナは、Event ハンドラと呼ばれ、ポートレット編集画面で登録することによって利用できます。
    Action ハンドラで Event を設定された場合のみ実行されます。

ポートレットのライフサイクルごとに、以下のように作成するファイルが異なります。

render 必須 JavaEE 開発モデルの画面。主 JSP と HelperBean。
processAction 任意 handleAction PortletActionHandler インタフェースを実装した Java クラス。
processEvent 任意 PortletEventHandler インタフェースを実装した Java クラス。
全てのライフサイクル用プログラムを作成し、組み合わせることで1つのポートレットとして作成することも可能です。
ライフサイクルごとに別々に開発を行って、複数のポートレット間で組み合わせて利用できるように作成することも可能です。
次項より、ポートレットで利用可能な API と、各ライフサイクルでの実装方法について簡単に説明していきます。

5.2. ポートレットAPI

単純な画面表示のみのポートレットでは、ポートレットAPIを利用しなくても作成可能ですが、ポートレットの機能を最大限に利用するためには、ポートレット API を利用する必要があります。
特に Action 処理や Event 処理を行うためには、ポートレット API を利用しなくては実行できません。
このドキュメントでは、基本的な関数のみに絞って説明します。
全ての API については「ポータル API リスト」および「Portlet API2.0 のドキュメント」を参照してください。
ポートレット API2.0 のドキュメントは以下より取得してください。

5.2.1. PortalManager

JavaEE 開発モデルでは、PortletAPI2.0 をそのまま利用可能ですが、これらの API を簡単に利用するためのアクセッサとして、PortalManager クラスが用意されています。
jp.co.intra_mart.foundation.portal.common.PortalManager
PortalManager のそれぞれの関数については、次項以降で実際に利用する際に説明します。

5.3. ポートレットモード

JavaEE 開発モデルで作成されたポートレットは、ポートレットタイプが「JavaEE開発モデルポートレット」となります。
ポートレットモードの利用可否はページ種別ごとに設定され、「JavaEE開発モデルポートレット」の初期状態では、表示モードと編集モードが利用できます。

5.3.1. ポートレットモードの設定

ポートレット定義を変更し、ポートレットを初期化することでポートレットモードの設定を変更することができます。
  • ポートレット定義の変更
    ポートレットモードの設定は以下のファイルで管理されています。intra-mart Accel Platform を停止して設定後、再起動を行います。
    設定ファイル
    %CONTEXT_PATH%/WEB-INF/plugin/jp.co.intra_mart.portal.portlets.javaee_8.0.0/plugin.xml
    設定箇所
    <?xml version="1.0" encoding="utf-8"?>
    <plugin>
       <extension point="jp.co.intra_mart.portal.portlets">
          <portlet
              id="jp.co.intra_mart.portal.portlets.javaee"
              name="JavaeeFwPortlet"
              display-name="%display-name"
              description="%description"
              version="8.0.0"
              rank="1">
               <portlet-class>jp.co.intra_mart.foundation.portal.portlets.model.JavaeeFwPortlet</portlet-class>
               <expiration-cache>0</expiration-cache>
               <supports>
                   <mime-type>text/html</mime-type>
                   <portlet-mode>VIEW</portlet-mode>
                   <portlet-mode>EDIT</portlet-mode>
                   <!-- ここにモードを追加 -->
               </supports>
               ...
          </portlet>
       </extension>
    </plugin>
    

5.3.2. ポートレットモードの取得

API を利用して、以下のように現在のポートレットモードを取得できます。
ポートレットモードは、以下のような「javax.portlet.PortletMode」クラスの定数が取得されます。

(ex.) PortletMode.VIEW, PortletMode.EDIT, PortletMode.HELP

javax.portlet.RenderRequest renderRequest = PortalManager.getRenderRequest();
javax.portletPortletMode portletMode = renderRequest.getPortletMode();

5.4. ウィンドウステータス

5.4.1. ウィンドウステータスの取得

API を利用して、以下のように現在のポートレットモードを取得できます。
ウィンドウステータスは、以下のような「javax.portlet.WindowState」クラスの定数が取得されます。
また、最小化時にはポートレットが呼び出されませんので、「WindowState.MINIMIZED」が取得されることはありません。

(ex.) WindowState.NORMAL, WindowState.MAXIMIZED, WindowState.MINIMIZED

javax.portlet.RenderRequest renderRequest = PortalManager. getRenderRequest();
javax.portlet.WindowState windowState = renderRequest. getWindowState();

5.5. 画面開発 (renderサイクル)

render サイクルでは、通常の Web ページと同様に画面表示が行われます。
JavaEE 開発モデルの画面は、おおむね通常の intra-mart の画面開発と変わりません。
ポートレット新規登録/編集画面 (「ポータル グループ管理者操作ガイド」参照)で設定されたページ引数は、HttpServletRequest オブジェクトの getParameter メソッドより取得することができます。
また、次項アクション処理、イベント処理によって設定されたリクエストパラメータも、HttpServletRequest オブジェクトより取得することができます。

5.5.1. RenderRequest, RenderResponse

ポートレットで利用する requestオブジェクトおよびresponse オブジェクトは、通常のWebページのリクエストは異なり、ポートレット表示時の専用のオブジェクトである、RenderRequestオブジェクトおよびRenderResponseオブジェクトを利用します。
これらのオブジェクトを利用することで、ポートレットの情報を取得することができます。
  • RenderRequest, RenderResponse の取得

    RenderRequest renderRequest = PortalManager.getRenderRequest();
    RenderResponse renderResponse = PortalManager.getRenderResponse();
    

    ただし、通常の Web ページと共用できるように、ページ引数は、HttpServletRequest オブジェクト(JSP で「request」キーワードによりアクセスされる)を利用して取得することも可能です。

  • JSP でのページ引数の取得

    <%
    RenderRequest renderRequest = PortalManager.getRenderRequest();
      // value1 と value2 は同じ値
      String value1 = request.getParameter("param1");
      String value2 = renderRequest.getParameter("param1");
    %>
    

    RenderRequest から、現在のポートレットモード、ウィンドウステータスなどが取得できます。

5.5.1.1. RenderRequestのスコープ

RenderRequest は通常の Web アプリケーションのリクエストとスコープが異なります。
全てのポートレットで独立したリクエストを保持しており、ポータル画面を表示する際のリクエストパラメータを引き継ぎません。
ただし以下のパラメータは、ポートレットコンテナにより、自動的に設定されます。
portal_cd ポートレットが配置されているポータル画面のキー。
portalKind

ポートレットが配置されているポータル画面のポータル種別。以下の値が取得される。

user ユーザポータル
group グループポータル
ポートレットにリクエストパラメータを設定するためには、アクション処理またはイベント処理を実行する必要があります。
また、一度設定したリクエストパラメータは、セッションが持続する間、再度アクション処理またはイベント処理が実行されるまで有効となります。

5.5.2. ActionURL, RenderURL

JavaEE 開発モデルで作成されたポートレットからサブミット処理を行い、 処理終了後に再びポータル画面を表示する機能を作成する場合には、ポートレットコンテナと通信するため、以下の URL に対してサブミットする必要があります。
ActionURL Action 機能を呼び出す URL
RenderURL ポータル画面を再表示するための URL
これらは、PortalManager を利用して取得することができます。
  • ActionURL, RenderURL の取得

    PortletURL actionURL = PortalManager.createActionURL();
    PortletURL renderURL = PortalManager.createRenderURL();
    
以下に、JavaEE 開発モデルで開発されたポートレットでサブミットされた後に、アクション処理を呼び出すサンプルを示します。
  • JSP

    <%
      PortletURL actionURL = PortalManager.createActionURL();
    %>
    <!-- 何らかの登録処理を行うサービスを呼び出す -->
    <form action="<%= actionURL.toString() %>" method="POST">
    <!-- 登録処理で使用する値 -->
      <input type="text" name="param1" value="">
      <input type="submit" value="実行">
    </form>
    
    • ポータル画面の表示には、「portal/desktop」というパスが割り振られています。
      そのため、このサービスID-URLにサブミットすることでもポータル画面の再表示が可能ですが、その場合ポータル情報を引き継ぐことができませんので、上記の方法を利用するようにしてください。
    • アクション処理を呼び出すためには、ActionURL にサブミットする以外にありません。
      ポートレット管理画面で Action ハンドラを登録し、プレゼンテーションページで ActionURL にサブミットするようにしてください。
      Action ハンドラが未定義の場合、単純にポータル画面を再表示します。
    • ActionURL はポータル情報を含むため、データ量が多くなります。メソッドは POST を指定するようにしてください。

5.5.3. 通常の画面とポートレット画面を共用するには

共用するコードと通常の画面のみ必要なコードを別々の JSP ページとして作成し、通常の画面用の JSP ページでは、include タグを利用して共用ページを読み込みます。
ただし、このような利用を行う場合はポートレットの各 API は利用できませんので注意してください。

<ポートレット画面と共用する通常画面のプレゼンテーションページ>

<html>
<head>
  <link src="sample.css" type="text/css">

</head>
<body>
    <div>
        ヘッダ表示情報
  </div>
  <!-- 共用コードをインクルードする -->
  <jsp:include page="sample/sample-portlet.jsp" flush="true"/>
    <div>
        フッタ表示情報
  </div>
</body>
</html>

5.6. アクション処理 (processActionサイクル)

processAction サイクルでは画面表示がありませんので、PortletActionHandler インタフェースを実装した Actionハンドラクラスのみ作成します。
さらにポートレット管理画面で作成した Action ハンドラを登録し、ActionURL へサブミットすることでアクション処理が実行されます。
アクション処理では、RenderParamter の設定、PortletPreference の設定、イベントの設定などの更新処理を行います。

5.6.1. Actionハンドラの作成

以下にイベントを設定する Action ハンドラの例を示します。
  1. PortletActionHandler インタフェースを実装した Java クラスを作成し、以下の関数を定義します。

    (この Java クラスを Action ハンドラと呼びます。)

    (ex.) sample.portal.SampleActionHandler.java

    // 「PortletActionHandler」インタフェースを実装する。
    public class SampleActionHandler implements PortletActionHandler {
      public Serializable handleAction(String portletCd, ActionRequest request, ActionResponse response) {
        // リクエスト引数を取得
        String value = request.getParameter("param1");
        // イベントを設定
        // intramart 用ポートレットにイベントを送信する場合、ImEvent オブジェクトを利用する。
        // QName は ImEvent.IM_QNAME を利用する。
        ImEvent event = new ImEvent();
        event.setEvent(value);
        response.setEvent(ImEvent.IM_QNAME, event);
        return null;
      }
    }
    
    • Action ハンドラは、render で利用するスクリプト開発モデルで作成されたファンクションコンテナを利用することもできます。
    • 以下のような値を return することでもイベントを発生させることができます。
      • jp.co.intra_mart.foundation.portal.common.handler .ImEvent のインスタンス
      • java.util.Map のインスタンス ・・・Map のキーと値をペアとするイベント
      • その他 ・・・ 文字列として判断し、キーと値が同じイベント

    ただし、IM 用ポートレットに対するイベントを発生させるためには、ImEvent クラスを利用するか、‘im_’ で始まるキーを指定する必要があります。

    • 詳細は「ポータル API リスト」の PortletActionHandler を参照してください。
  2. Action ハンドラをポートレットに登録します。

    portlet_regist_javaee

    <ポートレット新規登録画面>

  3. 画面開発 (renderサイクル) 」で作成した画面をポータル画面に配置し、ポートレットからアクション処理を呼び出します。

    Action処理実行後に、画面を再表示します。

    portlet_action_javaee

    <ポータル画面 - アクション処理>

5.6.2. ActionRequest, ActionResponse

Action ハンドラの引数は、アクション処理専用のオブジェクトである、ActionRequest オブジェクト、ActionResponseオブジェクトです。
これらのオブジェクトを利用することにより、リクエスト引数を取得したり、イベントを設定したりすることができます。
詳細は、「Portlet API2.0 ドキュメント」を参照してください。

5.6.3. RenderParameterの設定

画面表示時に取得可能なリクエストパラメータ(RenderParameter)は、アクション処理またはイベント処理の中で設定を行います。
アクション処理呼び出し時のリクエストパラメータは、ActionRequestに格納されていますが、 renderサイクルには引き継がれないため 、必要な場合は明示的に設定する必要があります。
また、アクション処理の呼び出し時には過去に設定された RenderParameter は全てクリアされています。

(ex.) processAction サイクルでの RenderParameter の設定

// リクエストパラメータを設定する場合。
response.setRenderParameter("param1", "value1");
// リクエストパラメータを削除する場合。
response.setRenderParameter("param2", null);

(ex.) render サイクルでの RenderParameter の利用

String value = request.getParamter("param1");

5.6.4. PortletPreferencesの設定

PortletPreferences とは、ユーザごとのポートレット情報保存領域です。
intra-mart Accel Platform のポートレットコンテナでは、PortletPreferences に設定された情報は、データベースに保存されます。
ここで設定された情報は、画面表示時にいつでも参照が可能です。

(ex.) javax.portlet.PortletPreferences の利用

// PortletPreferences の取得。
PortletPreferences preferences = request.getPreferences();
// PortletPreferences に設定された情報の取得。
String value = preferences.getValue("key1", "Default Value");
// PortletPreferences に情報を設定する。
preferences.setValue("key1", "value1");
// PortletPreferences を確定する。
//  この処理を行わない場合、情報は保存されません。
preferences.store();

5.6.5. イベントの設定

イベントを設定することにより、アクション処理を受け付けたポートレット以外の複数のポートレットにイベントの発生を通知して処理を引き渡すことが可能です。

(ex.) processEvent サイクルでのイベントの設定

response.setEvent(eventId, eventValue);

5.6.6. 利用可能なActionハンドラ

intra-mart Accel Platform では、以下の Action ハンドラが標準で用意されています。

5.6.6.1. jp.co.intra_mart.foundation.portal.common.handler.DefaultPortletHandler

ポートレット新規登録/編集画面で、Action ハンドラチェックボックスにチェックを行うと、初期値としてこの Actionハンドラが設定されます。
この Action ハンドラは、リクエストパラメータから値を取得して、そのキーと値を用いてイベントを発生させます。
単純に画面からイベントを発生させたいだけの場合、Action ハンドラを作成せずに、このハンドラを利用することが可能です。
イベントを発生させるためには、以下のリクエストパラメータを設定します。
  • “portlet.event.” + 任意の文字列

これにより、以下のイベントが作成されます。

プロパティ名 内容
id リクエストパラメータキーの任意の文字列
value リクエストパラメータの値

リクエストパラメータに複数設定することで、複数のイベントを発生させることも可能です。

5.6.6.2. jp.co.intra_mart.foundation.portal.common.handler.SetRenderParameterHandler

ポータル画面表示時のリクエストパラメータは、ポートレットとスコープが異なるため、ポートレット内の処理からは取得できません。
この Action ハンドラを設定することで、ポータル画面表示時のリクエストパラメータをポートレットで利用することが可能となります。

5.7. イベント処理 (processEventサイクル)

processEvent サイクルでは画面表示がありませんので、PortletEventHandler インタフェースを実装した Event ハンドラクラスのみ作成します。
さらにポートレット管理画面で作成した Event ハンドラを登録し、任意のポートレットのアクション処理でイベントが設定されることにより、イベント処理が実行されます。
イベント処理では、RenderParamter の設定、PortletPreferences の設定、イベントの設定などの更新処理を行います。

5.7.1. Eventハンドラの作成

以下に RenderParameter を設定する Event ハンドラの例を示します。
  1. PortletEventHandler インタフェースを実装した Java クラスを作成し、以下の関数を定義します。

    (この Java クラスを Event ハンドラと呼びます。)

    (ex.) sample.portal.SampleEventHandler.java

    // 「PortletEventHandler」インタフェースを実装する。
    public class SampleEventHandler implements PortletEventHandler {
      public Serializable handleEvent(String portletCd, EventRequest request, EventResponse response) {
        // イベントオブジェクトを取得
        // intramart 用ポートレット間で利用するイベントオブジェクトは、「ImEvent」になります。
        ImEvent event = (ImEvent) request.getEvent().getValue();
        // 画面表示に利用するリクエストパラメータを設定
        response.setRenderParameter(event.getEventId(), event.getEvent());
        return null;
      }
    }
    
    • Event ハンドラは、render で利用するスクリプト開発モデルで作成されたファンクションコンテナを利用することもできます。

    • 戻り値を設定することで、さらにイベントを発生させることができます。
      ※ループしないように注意して設計してください。
  2. Event ハンドラをポートレットに登録します。

    portlet_regist2_javaee

    <ポートレット新規登録画面>

  3. 作成したイベントを呼び出すことができるポートレットをポータル画面に配置し、イベントを設定するポートレットからアクション処理を呼び出します。

    アクション処理からEventハンドラが実行され、その後、画面を再表示します。

    portlet_action2_javaee

    <ポータル画面 - イベント処理>

5.7.2. ImEventオブジェクト

EventRequestから取得できる Eventオブジェクトは、intramartのポートレット間では、ImEventオブジェクトが設定されます。
ImEvent オブジェクトは以下の情報を格納しています。
プロパティ名
id String
アクション処理で設定されたイベント ID
省略された場合、文字列「ImEvent」が設定される。
value String
アクション処理で設定されたイベントの値
オブジェクトを設定した場合も文字列として取得される。
source String Event を設定したポートレットのポートレットコード

5.7.3. EventRequest, EventResponse

Event ハンドラの引数は、イベント処理専用のオブジェクトである、EventRequest オブジェクト、EventResponse オブジェクトです。
これらのオブジェクトを利用することにより、リクエスト引数を取得したり、さらにイベントを設定したりすることができます。
詳細は、「Portlet API2.0 ドキュメント」を参照してください。

5.7.4. RenderParameterの設定

画面表示時に取得可能なリクエストパラメータ(RenderParameter)は、アクション処理またはイベント処理の中で設定を行います。
イベント処理呼び出し時に設定済みであった RenderParameter は、EventRequest に格納されており、特に処理を行わない限り、 render サイクルに自動的に引き継がれます
引継ぎが不要な場合は明示的に削除する必要があります。

(ex.) processEvent サイクルでの RenderParameter の設定

// リクエストパラメータを設定する場合。
response.setRenderParameter("param1", "value1");
// リクエストパラメータを削除する場合。
response.setRenderParameter("param2", null);

(ex.) render サイクルでの RenderParameter の利用

request.getParamter(eventId);

5.7.5. PortletPreferencesの設定

PortletPreferences とは、ユーザごとのポートレット情報保存領域です。
intra-mart Accel Platform のポートレットコンテナでは、PortletPreferences に設定された情報は、データベースに保存されます。
ここで設定された情報は、画面表示時にいつでも参照が可能です。

(ex.) java.portlet.PortletPreferences の利用

// PortletPreferences の取得。
PortletPreferences preferences = request.getPreferences();
// PortletPreferences に設定された情報の取得。
String value = preferences.getValue("key1", "Default Value");
// PortletPreferences に情報を設定する。
preferences.setValue("key1", "value1");
// PortletPreferences を確定する。
//  この処理を行わない場合、情報は保存されません。
preferences.store();

5.7.6. イベントの設定

イベントを設定することにより、イベント処理を受け付けたポートレット以外の複数のポートレットにイベントの発生を通知して処理を引き渡すことが可能です。
ただし、イベント処理でさらにイベント処理を行うとパフォーマンスの低下をまねき、またイベントループの発生する可能性もありますので、十分注意して実装してください。

(ex.) processEvent サイクルでのイベントの設定

response.setEvent(eventId, eventValue);

5.8. 「重要なお知らせ」ポートレットについて

ポータルモジュールには、汎用的な新着情報を表示する「重要なお知らせ」ポートレットが用意されています。
この「重要なお知らせ」ポートレットでは、新着情報として以下の項目を表示します。
  • 新着情報の種類を示すためのカテゴリ
  • 新着情報の内容(概要)
  • 配信日付
  • 新着情報に紐付く遷移先の情報(リンク)
「重要なお知らせ」ポートレットに独自の新着情報を表示させるためには、下記の手順で新着情報を追加します。
  1. 新着情報を取得するプロバイダを実装する。
    新着ポートレットに表示される情報は、以下のインタフェースを実装したプロバイダより取得されます。
    • 「重要なお知らせ」新着情報のプロバイダーのインタフェース

      jp.co.intra_mart.foundation.portal.general_purpose_portlet.provider.NewArrivedProvider

    「重要なお知らせ」ポートレットに、以下のプロバイダを利用して、パスワード履歴管理情報を表示しています。
    独自のプロバイダを実装する場合の参考にしてください。
    • パスワード履歴管理「重要なお知らせ」新着情報のプロバイダ

      jp.co.intra_mart.foundation.security.password.PasswordHistoryNewArrivedProvider

    プロバイダのインタフェースおよびプロバイダの実装についての詳細は「ポータル API リスト」を参照してください。
  2. プロバイダの実装を定義する。
    実装したプロバイダクラスについての情報は、%PUBLIC_STORAGE_PATH%/portal/system_notice.xml に 以下の情報を定義します。

    <プロバイダ設定ファイル>

    要素 説明
    new-arrived-portlet/sort 取得した新着情報をカテゴリでソートするかどうかを定義します。
    new-arrived-portlet/provider/provider-class プロバイダの実装クラスを定義します。
    new-arrived-portlet/provider/init-param プロバイダクラスに設定する初期化パラメータを定義します。

    以下に設定ファイルの記述例を示します。

    <system_notice.xml>

    <new-arrived-portlet>
      <sort>true</sort>
          :
          :
      <provider>
            <provider-class>
                sample.SampleProvider
            </provider-class>
            <init-param>
                <param-name>param1</param-name>
                <param-value>hogehoge</param-value>
            </init-param>
      </provider>
    </new-arrived-portlet>
    
    プロバイダを複数登録して、複数の新着情報を1つのポートレットに表示することも可能です。