ヘッダーをスキップ
Oracle® Fusion Middleware Oracle WebCenter Portal開発者ガイド
11g リリース1 (11.1.1.6.0)
B72084-01
  ドキュメント・ライブラリへ移動
ライブラリ
製品リストへ移動
製品
目次へ移動
目次
索引へ移動
索引

前
 
次
 

59 Oracle JSF Portlet Bridgeを使用したポートレットの作成

この章では、Oracle JSF Portlet Bridgeを使用して、アプリケーションをポートレットとして公開する方法を説明します。

この章の内容は、次のとおりです。

59.1 Oracle JSF Portlet Bridgeの概要

Oracle JSF Portlet Bridgeを使用すると、アプリケーション開発者は、既存のJSFアプリケーション、Oracle ADFアプリケーションおよびタスク・フローをJSR 286ポートレットとして簡単に公開できます。


注意:

特に記載がないかぎり、JSFアプリケーションにはOracle ADFアプリケーションも含まれます。


Oracle JSF Portlet Bridgeを使用すると、次のことが可能になります。


注意:

Oracle JSF Portlet Bridgeは、JSR 329に基づきかつ準拠しています。JSR 329は、JavaServer Faces向けのポートレット2.0ブリッジの機能を定義する標準化の取組みです。オラクル社はこの標準のスペシフィケーション・リードです。詳細は、次で参照できます。

http://www.jcp.org/en/jsr/detail?id=329

59.2 JSFアプリケーションからのポートレットの作成

Oracle JSF Portlet Bridgeを使用すると、JSFアプリケーションまたはタスク・フローをポートレットとして公開できます。「ポートレット・エントリの作成」ダイアログを使用して宣言することで実行でき、コーディングは必要ありません。「ポートレット・エントリの作成」ダイアログを使用すると、JSFアプリケーションでOracle JSF Portlet Bridgeを構成し、アプリケーションをJSR 286ポートレットとして公開できます。この構成の一部として、初期JSFビュー(またはタスク・フロー・ビュー)を指定し、ポートレットのレンダリング時に起動するようにします。それ以降、Oracle JSF Portlet BridgeはJSFアプリケーションと連携し、この初期ビューから使用可能な追加のビューを通してナビゲートします。そのため通常、JSFアプリケーション全体をポートレットとして公開する場合は、ポートレットでアプリケーションの初期ビューをレンダリングするようOracle JSF Portlet Bridgeを構成すると、他のナビゲーションは自然にその同じポートレット内で動作するようになります。

この項の内容は、次のとおりです。

59.2.1 ページに基づいたJSFポートレットの作成方法

JSFアプリケーションからポートレットを作成する最も簡単な方法は、ページに基づいたポートレットを生成することです。

既存のアプリケーション・ページからJSFポートレットを作成する方法は、次のとおりです。

  1. JDeveloperのアプリケーション・ナビゲータで、ポートレット化する.jspxページを含むアプリケーションを開きます。

  2. ポートレット化するページを右クリックし、「ポートレット・エントリの作成」を選択します。

  3. 「ポートレット・エントリの作成」ダイアログ(図59-1)の「ポートレット名」フィールドで、ポートレット名を入力します。

    図59-1 ページ用の「ポートレット・エントリの作成」ダイアログ

    図59-1の説明が続きます
    「図59-1 ページ用の「ポートレット・エントリの作成」ダイアログ」の説明

  4. 「表示名」フィールドに、ポートレットに対する説明的な名前を入力します。

  5. 「ポートレット・タイトル」フィールドに、ポートレットに対する説明的なタイトルを入力します。

    ポートレットのタイトルは「リソース・パレット」または「アプリケーション・リソース」パネルに表示されるため、有用なポートレットがどれかをユーザーが特定できるようなタイトルにします。ポートレット・タイトルは、ポートレットがページ上に現れるときに、ポートレット・ヘッダーにも表示されます。

  6. 「短いタイトル」フィールドに、ポートレットのより短いタイトルを入力します。短いタイトルは、ポートレットがモバイル・デバイスのページ上に現れるときに、ポートレット・ヘッダーに表示されます。

  7. 「説明」フィールドに、ポートレットの説明を入力します。

  8. 「コンテキスト・イベント用ポートレット・イベントの作成」を選択して、ページにより公開されるすべてのコンテキスト・イベント用のportlet.xmlファイルにポートレット・イベントを作成します。このオプションはデフォルトで選択されています。

    ポートレット・イベントを使用すると、ポートレットと、ポートレットが存在するページ間およびそのページに存在する他のポートレット間の通信が可能になります。

  9. 「OK」をクリックします。

    portlet.xmlファイルが作成されます。

    このファイルにはポートレット・エントリ(例59-1)が含まれており、表示や編集が可能な状態で開かれます。デフォルトでは、このファイルは「デザイン・ビュー」で開かれます。ソース・コードを表示または編集するには、「ソース」タブをクリックします。

    例59-1 ページ用に生成されたポートレット・エントリ

    <portlet id="adf_jsf__testPage_jspx">
      <description>PortletBridgeApplication_testPage_jspx</description>
      <portlet-name>PortletBridgeApplication_testPage_jspx</portlet-name>
      <display-name>PortletBridgeApplication_testPage_jspx</display-name>
      <portlet-class>
        oracle.portlet.bridge.adf.application.ADFBridgePortlet
      </portlet-class>
      <init-param>
        <name>javax.portlet.faces.defaultViewId.view</name>
        <value>/myPage.jspx</value>
      </init-param>
      <supports>
        <mime-type>text/html</mime-type>
        <portlet-mode>VIEW</portlet-mode>
      </supports>
      <supported-locale>en</supported-locale>
      <portlet-info>
        <title>PortletBridgeApplication_testPage_jspx</title>
        <short-title>PortletBridgeApplication_testPage_jspx</short-title>
      </portlet-info>
      <supported-processing-event id="DepartmentSelectedEvent">
        <qname xmlns:x="http://xmlns.oracle.com/adfm/contextualEvent">
          x:DepartmentSelectedEvent
        </qname>
      <supported-publishing-event id="DepartmentSelectedEvent">
        <qname xmlns:x="http://xmlns.oracle.com/adfm/contextualEvent">
          x:DepartmentSelectedEvent
        </qname>
      </supported-publishing-event>
      <supported-public-render-parameter>
        _adf_event_DepartmentSelectedEvent
      </supported-public-render-parameter>
      <container-runtime-option>
        <name>com.oracle.portlet.requireIFrame</name>
        <value>true</value>
      </container-runtime-option>
      <container-runtime-option>
        <name>com.oracle.portlet.minimumWsrpVersion</name>
        <value>2</value>
      </container-runtime-option>
    </portlet>
    

    先ほど選択したページは、ポートレットの表示モードのエントリ・ポイントとして使用されます。これはportlet.xmlファイルのjavax.portlet.faces.defaultViewId.view初期化パラメータで指定されています。portlet.xmlファイルは手動で編集して他のデフォルトのページを定義したり、WebCenter Portalでサポートされている次の拡張ポートレット・モードを定義したりできます。

    • 編集モード: javax.portlet.faces.defaultViewId.edit

    • ヘルプ・モード: javax.portlet.faces.defaultViewId.help

    • 情報モード: javax.portlet.faces.defaultViewId.about

    • 構成モード: javax.portlet.faces.defaultViewId.config

    • デフォルト編集モード: javax.portlet.faces.defaultViewId.edit_defaults

    • プレビュー・モード: javax.portlet.faces.defaultViewId.preview

    • 印刷モード: javax.portlet.faces.defaultViewId.print


    注意:

    defaultViewIdの値はアプリケーションのコンテキスト・ルートと関連しており、必ず/で始まる必要があります。たとえば、例59-1では、defaultViewId.viewの値は/myPage.jspxです。

    他のポートレット・モードのdefaultViewIdを追加する場合は、<supports>タグにも必ずモードを追加するようにします。たとえば、<portlet-mode>HELP</portlet-mode>のようになります。


59.2.2 タスク・フローに基づいたJSFポートレットの作成方法

Oracle ADFを使用する利点は、タスク・フローによりモジュール単位でアプリケーションに制御フローを定義できることです。アプリケーションを単一の大規模なJSFページ・フローとして表すかわりに、再利用可能なタスク・フローのコレクションに分割できます。各タスク・フローで、アプリケーション・アクティビティと、アプリケーションで完了するために実行する必要のある作業ユニットを識別します。アクティビティは、タスク・フローの実行中に処理できる作業を表します。

タスク・フローは、バインドにすることも、バインドなしにすることもできます。

  • バインドなしタスク・フローは、アクティビティ、制御フロー・ルールおよびユーザーがタスクを完了できるように作用するマネージドBeanのセットです。バインドなしタスク・フローは、バインド・タスク・フローには含まれない、アプリケーションのすべてのアクティビティおよび制御フローで構成されています。

  • バインド・タスク・フローは、単一のエントリ・ポイントと1つ以上の終了ポイントを持つ、特別な形式のタスク・フローです。独自のプライベート制御フロー・ルール、アクティビティおよびマネージドBeanのセットが含まれます。Oracle ADFバインド・タスク・フローでは、パラメータの再利用、トランザクション管理および再エントリが可能です。終了ポイントはゼロ以上にできます。

典型的なアプリケーションでは、1つのバインドなしタスク・フローと、1つ以上のバインド・タスク・フローが組み合されています。アプリケーションは、バインドなしタスク・フロー内のアクティビティからバインド・タスク・フローをコールできます。バインド・タスク・フローおよびバインドなしタスク・フローの詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Fusion開発者ガイド』を参照してください。

この項の内容は、次のとおりです。

59.2.2.1 「ポートレット・エントリの作成」ダイアログを使用したタスク・フローからのポートレット作成

「ポートレット・エントリの作成」ダイアログを使用して単一のタスク・フローからポートレットを作成します。

「ポートレット・エントリの作成」ダイアログを使用してタスク・フローからポートレットを作成する手順は次のとおりです。

  1. JDeveloperのアプリケーション・ナビゲータで、ポートレットを作成するタスク・フローが含まれるJSFアプリケーションを開きます。

  2. ポートレット化するタスク・フローを右クリックし、「ポートレット・エントリの作成」を選択します。

  3. 「ポートレット・エントリの作成」ダイアログ(図59-2)の「ポートレット名」フィールドで、ポートレット名を入力します。

    図59-2 タスク・フロー用の「ポートレット・エントリの作成」ダイアログ

    図59-2の説明が続きます
    「図59-2 タスク・フロー用の「ポートレット・エントリの作成」ダイアログ」の説明

  4. タスク・フローがバインドなしの場合、タスク・フローのすべてのビュー・アクティビティが「エントリ・ポイント・ビュー」ドロップダウン・リストに表示されます。このドロップダウン・リストから、ポートレットのエントリ・ポイントとして使用するビュー・アクティビティを選択します。デフォルトでは、タスク・フローの先頭のビュー・アクティビティが選択されています。

    タスク・フローがバインドの場合、エントリ・ポイントは1つのみなので、「エントリ・ポイント・ビュー」ドロップダウン・リストは表示されません。

  5. 「表示名」フィールドに、ポートレットに対する説明的な名前を入力します。

  6. 「ポートレット・タイトル」フィールドに、ポートレットに対する説明的なタイトルを入力します。

    ポートレットのタイトルは「リソース・パレット」または「アプリケーション・リソース」パネルに表示されるため、有用なポートレットがどれかをユーザーが特定できるようなタイトルにします。ポートレット・タイトルは、ポートレットがページ上に現れるときに、ポートレット・ヘッダーにも表示されます。

  7. 「短いタイトル」フィールドに、ポートレットのより短いタイトルを入力します。短いタイトルは、ポートレットがモバイル・デバイスのページ上に現れるときに、ポートレット・ヘッダーに表示されます。

  8. 「説明」フィールドに、ポートレットの説明を入力します。

  9. 「コンテキスト・イベント用ポートレット・イベントの作成」を選択して、タスク・フローにより公開されるすべてのコンテキスト・イベント用のportlet.xmlファイルにポートレット・イベントを作成します。このオプションはデフォルトで選択されています。

    ポートレット・イベントを使用すると、ポートレットと、ポートレットが存在するページ間およびそのページに存在する他のポートレット間の通信が可能になります。

  10. 「OK」をクリックします。

    ポートレットが作成されると、次のようなメッセージが表示されます。

    New portlet has been successfully created
    

    さらに、portlet.xmlファイルが作成されます。portlet.xmlファイルにはポートレット・エントリ(例59-2)が含まれており、表示や編集が可能な状態で開かれます。

    例59-2 タスク・フロー用に生成されたポートレット・エントリ

    <portlet id="adf_taskflow_WEB_INF_department_xml">
        <description>PortletBridgeApplication department</description>
        <portlet-name>PortletBridgeApplication_department</portlet-name>
        <display-name>PortletBridgeApplication department</display-name>
        <portlet-class>oracle.portlet.bridge.adf.application.ADFBridgePortlet</portlet-class>
        <init-param>
          <name>javax.portlet.faces.defaultViewId.view</name>
          <value>
            /adf.task-flow?adf.tfDoc=/WEB-INF/adfp-portlet-bridge-container.xml
            &amp;adf.tfId=adfp-portlet-bridge-container&amp;_fragmentTaskFlowDoc=/WEB-INF/
            department.xml&amp;_fragmentTaskFlowId=department
          </value>
        </init-param>
        <supports>
          <mime-type>text/html</mime-type>
          <portlet-mode>VIEW</portlet-mode>
        </supports>
        <supported-locale>en</supported-locale>
        <portlet-info>
          <title>PortletBridgeApplication department</title>
          <short-title>PortletBridgeApplication department</short-title>
        </portlet-info>
        <supported-publishing-event id="DepartmentSelectedEvent">
          <qname xmlns:x="http://xmlns.oracle.com/adfm/contextualEvent">
            x:DepartmentSelectedEvent
          </qname>
        </supported-publishing-event>
        <supported-public-render-parameter>
          _adf_event_DepartmentSelectedEvent
        </supported-public-render-parameter>
        <container-runtime-option>
          <name>com.oracle.portlet.requireIFrame</name>
          <value>true</value>
        </container-runtime-option>
        <container-runtime-option>
          <name>com.oracle.portlet.minimumWsrpVersion</name>
          <value>2</value>
        </container-runtime-option>
    </portlet>
    

    注意:

    portlet.xmlファイルには複数のポートレットを含めることができるため、ポートレットとして公開されるページとタスク・フローが組み合されていることがあります。


59.2.2.2 「タスク・フローのポートレット・エントリの管理」ダイアログを使用したタスク・フローからのポートレット作成

プロジェクトに多数のタスク・フローが含まれる場合は、リストからタスク・フローを選択してポートレットを作成した方が簡単な場合があります。これは「タスク・フローのポートレット・エントリの管理」ダイアログを使用することにより可能です。このダイアログを使用すると、ポートレットを個別に作成するのではなく、複数のタスク・フローから同時にポートレットを作成することもできます。

「タスク・フローのポートレット・エントリの管理」ダイアログを使用してタスク・フローからポートレットを作成する手順は次のとおりです。

  1. メイン・メニューから、「ファイル」を選択し、「新規」を選択します。

  2. 「新規ギャラリ」で、「Web層」を開き、「ポートレット」を選択して、「タスク・フローのポートレット・エントリの管理」を選択し、「OK」をクリックします。

  3. 「タスク・フローのポートレット・エントリの管理」ダイアログで、シャトル・ボタンを使用してポートレットを作成するタスク・フローを選択します。

    図59-3 「タスク・フローのポートレット・エントリの管理」ダイアログ

    図59-3の説明が続きます
    「図59-3 「タスク・フローのポートレット・エントリの管理」ダイアログ」の説明

  4. 「コンテキスト・イベント用ポートレット・イベントの作成」を選択して、タスク・フローにより公開されるすべてのコンテキスト・イベント用のportlet.xmlファイルにポートレット・イベントを作成します。このオプションはデフォルトで選択されています。

    ポートレット・イベントを使用すると、ポートレットと、ポートレットが存在するページ間およびそのページに存在する他のポートレット間の通信が可能になります。

  5. 「OK」をクリックすると、選択されたタスク・フローのポートレットが作成されます。

59.2.3 統合WebLogic Serverを使用したJSFポートレットのテスト方法

JSFポートレットの作成後は、JDeveloperとともにパッケージ化されている統合WebLogic Serverを使用してテストできます。

JSFポートレットをテストするには、次の手順を実行します。

  1. メイン・メニューから、「実行」を選択し、「サーバー・インスタンスの起動」を選択します。

    統合WLSの起動には少し時間がかかる場合があります。インスタンスが起動されると、「ログ」パネルに次のようなメッセージが表示されます。

    IntegratedWebLogicServer started.
    

    詳細は、第3.4項「統合WebLogic Serverの使用」を参照してください。

  2. これでポートレット・プロデューサ・アプリケーションを統合WLSで実行またはデプロイできます。Webアプリケーションとポートレット・プロデューサ・アプリケーションは1つのもの(ポートレット・プロデューサ・アプリケーションは、既存のWebアプリケーションにポートレット・アーティファクトを追加したもの)なので、通常どおりにWebアプリケーションを実行またはデプロイすることも、第62.2.1項「統合WebLogic ServerでのJSR 286ポートレットのテスト方法」の手順に従ってポートレットを実行またはデプロイすることもできます。

    前述の項の注意にある、実行とデプロイとの違いに注意してください。デプロイではより持続的なテスト・シナリオが使用できます。

  3. デプロイした場合、次へ移動することにより「プロデューサ・テスト・ページ」を表示できます。

    http://host:port/context-root/info
    

    デプロイ後は、アプリケーションがWebアプリケーションとして正しく動作することを検証してから、ポートレット・プロデューサ・アプリケーションとして使用する必要があります。たとえば、先ほどポートレット化したページが動作することを次で検証します。

    http://localhost:7101/myApp-ViewController-context-root/faces/myPage.jspx
    
  4. ポートレットを含むアプリケーションのデプロイに成功すると、それを他の任意のアプリケーションにポートレット・プロデューサとして登録できます。詳細は、第64.2.1項「WSRPポートレット・プロデューサの登録方法」を参照してください。


    注意:

    Oracle JSF Portlet Bridgeは、WSRP 2.0の機能を使用しているため、WSRPプロデューサ・テスト・ページにリストされているWSRP v2 WSDL URLを使用してプロデューサを登録する必要があります。


    アプリケーションは、通常のWebアプリケーションとして引き続きアクセスすることも、ポートレット・プロデューサとして使用することもできます。

  5. ポートレット・プロデューサをデプロイし、登録すると、自分のJSFポートレットを他のポートレットと同じように使用できます。詳細は、第64.3項「ページへのポートレットの追加」を参照してください。

59.2.4 実行時の処理

JSFポートレットを作成し、テストした後は、アプリケーションを本番環境にデプロイできます。


注意:

Oracleポートレット・コンテナがインストールされたJava EEコンテナにアプリケーションをデプロイしてください。統合WLSには、コンテナがインストールされています。これが、テストにお薦めする理由です。


正常にデプロイしたら、アプリケーションおよびポートレット・プロデューサのテスト・ページの両方にアクセスできます。たとえば、アプリケーションURLは次のようになります。

http://host:port/appcontextroot/faces/pagename.jspx

ポートレット・プロデューサのテストURLは次のようになります。

http://host:port/appcontextroot/info

詳細は、第64.2.1項「WSRPポートレット・プロデューサの登録方法」を参照してください。

59.3 JSFポートレットの作成時に必要な知識

JSR 286ポートレット・マークアップ・フラグメント・ルールに準拠するマークアップを生成するように、JSFページをコーディングする必要があります。Oracle ADFの使用を選択した場合は、ページのマークアップの大部分は、Oracle ADF Facesのコンポーネントからのもので、コンポーネントの大部分では、マークアップは当然、JSFポートレットと互換性のあるスタイルでレンダリングされます。

ポートレット環境で問題を起こす可能性のあるコンポーネントについては、アプリケーション開発者は特に注意が必要です。一部のコンポーネントでは、ポートレット環境と競合するマークアップが生成されるため、その使用が制限されます。その他のコンポーネントでは、開発者がポートレット環境と競合する値を把握できるプログラム制御(入力)を使用できます。この場合、開発者は、ページをポートレットとして公開する可能性について認識し、その結果、値を正しくエンコードする必要があります。

この項の内容は、次のとおりです。

59.3.1 一般的ガイドライン

この後のガイドラインでは、ポートレットとして公開することになるOracle ADFページをコーディングするときに知っておく必要のある問題について説明します。

  • JSFアプリケーションからポートレットを作成するには、統合WLSへのデプロイ後に、アプリケーション(すべてのページおよびタスク・フローを含む)が正常に実行されている必要があります。通常のWebアプリケーションとして実行できない場合は、ポートレット・プロデューサとしても実行できません。

  • サーブレット環境とポートレット環境の両方で実行されるアプリケーションを作成する場合は、HttpServletオブジェクトへのキャストを避けます(そうしないと、ポートレットとして実行したときにClassCastExceptionが発生します)。そのかわりに、FacesのExternalContextオブジェクトによって提供される抽象化を使用します。たとえば、次のコードの使用は避けます。

    HttpServletRequest request =
    (HttpServletRequest)FacesContext().getCurrentInstance().getExternalContext()
    .getRequest();
    

    次のコードを使用します。

    String localContextPath=
    FacesContext().getCurrentInstance().getExternalContext().getRequestContextPath();
    

    ExternalContextによりそのような抽象化が提供されていない場合にかぎり、サーブレットまたはポートレットに固有のコードを作成します。次のメソッドを使用して、アプリケーションがポートレットとして実行されているかどうかをチェックします。

    public static boolean isPortletRequest() {
        Map<String, Object> m =
            FacesContext.getCurrentInstance().getExternalContext().getRequestMap();
        Object phase = m.get("javax.portlet.faces.phase");
        if (phase != null) {
            return true;
        }
        else {
            return false;
        }
    }
    
  • JSFポートレットを使用する場合、コンシューマ・アプリケーションはインライン・フレーム(IFRAME)内のポートレット・コンテンツを自動的にレンダリングします。これは、すべてのインライン・ポップアップはIFRAME内に限定されることを意味します。このことを考慮してポートレットのサイズを指定する必要があります。

  • アプリケーションが保護されている場合は、第69.17項「WS-Securityを使用したWSRPプロデューサを介するアイデンティティ伝播の保護」で説明されているように、アイデンティティ伝播を保護してください。

  • ディープ・リンクは、直接サポートされません。WSRPでのJSR 286ポートレット・コンテナ実装の副産物として、セッションCookie管理は、クライアントではなく、ポートレットを使用するアプリケーションが代行します。完全サービスのアプリケーションまでのディープ・リンクが張られているポートレットは、通常、共有セッションの状態に依存しているため、現行のポートレット・コンテキストからの遷移が可能です。大部分のアプリケーションがCookieによるセッション・コンテキストの保持に依存しているため、現行のアーキテクチャでは、そのような状態の共有はできません。クライアントから、アプリケーションを起動するプロデューサ・サーバーに直接つながるディープ・リンクでは、コンシューマとプロデューサ間にセッションCookieが確立されないため、もう1つのセッションが確立されます。そのような状態の共有を必要とするアプリケーションでは、2つのコンテキスト間でデータを転送するための独自のスキームを実装する必要があります。共通実装とは、この状態を使用できる場所に書き込み、この状態に対する参照をディープ・リンクで渡しことです。

  • Java EEログインはサポートされません。Java EEアプリケーションは、様々な認証テクニック(BasicとDigestなど)により構成できます。ポートレットは、コンシューマのページに組み込まれたフラグメントであるので、一般には、クライアントとポートレット・プロデューサ間ではなく、クライアントとコンシューマ間で直接認証が行われることが予想されます。その結果、これらの認証テクニックは、JSR 286ではサポートされません。JSR 286の場合は、Java EE認証が、WSセキュリティ・メカニズムを介して行われます。WS-Securityでは、Webサービスのコンシューマがプロデューサによって認証および検証され、ユーザー認証および認可用のユーザー・アイデンティティが伝播されます。公開されるOracle ADFアーティファクトには、Java EE認証を起動するログイン・リンクを含めないでください。

  • レンダリングに時間を要するアプリケーションに対しては、Oracle JSF Portlet Bridgeにより作成されたプロデューサの登録時に、タイムアウト期間を増やすことを検討します。ただし、プロデューサの登録時に指定するタイムアウト期間は、adf-config-xmlに指定されている最大タイムアウト期間(maximumTimeout要素)によって制限されることに注意してください。

59.3.2 ポートレットのガイドライン

ポートレットのガイドラインは次のとおりです。

  • リソースおよびリンクについては、web-app-context-rootを基準として場所を指定する必要があります。そうしないと、ポートレットがイメージやその他のリソースを見つけられません。相対パスの表記(../)を使用しないでください。Oracle WebCenter Portal: Frameworkのポートレットは、リモートで実行され、SOAPプロトコル(WSRP)を使用してアクセスされます。後者は、通常のWebアプリケーションのリクエスト・パスの概念が、JSR 286コンテナには適用されないということです。JSR 286仕様では、すべてのリソースURLが絶対パスまたはコンテキスト相対パスのいずれかであることが規定されていることにこれが反映されています。

  • リクエストをJSP内でリダイレクトまたは転送しないでください。JSR 286では、requestDispatcher.include()のみがサポートされています。httpServletResponse.sendRedirect()またはrequestDispatcher.forward()を使用すると、例外やエラーが発生します。ポートレット環境で正常に作業を行うには、faces-config.xmlまたはOracle ADFタスク・フローの制御フロー・ルールにJSFナビゲーションを実装する必要があります。

  • ポートレットとしての実行時に、アプリケーションでの全体のメモリー消費を最小限に抑えるには、リクエスト・スコープに最小限のデータのみを格納します。

  • ダウンロード可能なリソースを含むアプリケーションをポートレット化する場合は、ポートレット・コンテナによりブラウザで開いたり保存したりするには長すぎるファイル名に書き換えられることがあります。その場合は、リソースを別名で保存し、適切なプログラムを使用してファイルを直接開くことができます。

  • ポートレットがADF Faces (たとえば、Trinidadコンポーネント)以外のJSFビュー・コンポーネントを使用する場合、WSRP V1 WSDLを使用して登録可能にするため、ポートレットのminimumWsrpVersionコンテナ実行時オプションを、手動で1に変更することもできます。詳細は、第61.2.4項「実行時環境のカスタマイズ方法」を参照してください。

59.3.3 セキュリティのガイドライン

セキュリティのガイドラインは次のとおりです。

  • 「ポートレット・エントリの作成」ダイアログまたは「タスク・フローのポートレット・エントリの管理」ダイアログを使用して、Oracle ADFの保護されたアプリケーション(セキュリティ・スキームが認証および認可)内のタスク・フローをポートレット化する場合は、プロデューサ・アプリケーションのjazn-data.xmlファイルの、次のラッパー・タスク・フローに手動で権限を付与する必要があります。

    /WEB-INF/adfp-portlet-bridge-container.xml#adfp-portlet-bridge-container
    

    権限を付与しないと、ポートレットはレンダリングされません。

    たとえば、表示権限を持つ認証ロールとカスタマイズ、編集、権限付与、パーソナライズおよび表示権限を持つテストロールの2つのロールを持つアプリケーションがある場合、各ロールの<permissions>タグ内に次のエントリを追加する必要があります。

    • 認証ロール用

      <permission>
        <class>oracle.adf.controller.security.TaskFlowPermission</class>
        <name>
        /WEB-INF/adfp-portlet-bridge-container.xml#adfp-portlet-bridge-container
        </name>
        <actions>view</actions>
      </permission>
      
    • テストロール用

      <permission>
        <class>oracle.adf.controller.security.TaskFlowPermission</class>
        <name>
          /WEB-INF/adfp-portlet-bridge-container.xml#adfp-portlet-bridge-container
        </name>
        <actions>customize,edit,grant,personalize,view</actions>
      </permission>
      
  • ロール・ベースの認可を持つ(つまり、タスク・フローまたはページに特定のロールが付与されている)タスク・フローまたはページをポートレット化する場合、ユーザーを正しく伝播するにはWS-Securityが必要です。WS-Securityを設定すると、JSFポートレットは権限がないためコンテンツをレンダリングしません。

    プロデューサでのWS-Security設定の詳細は、第69.17項「WS-Securityを使用したWSRPプロデューサを介するアイデンティティ伝播の保護」を参照してください。

    使用するアプリケーションにプロデューサを登録する場合は、必ず適切なセキュリティ・プロパティを設定する必要があります。詳細は、第64.2.1項「WSRPポートレット・プロデューサの登録方法」を参照してください。

59.3.4 JSFのガイドライン

JSFのガイドラインは次のとおりです。

  • h:commandLink JSF標準HTMLコンポーネントを使用する場合は、必ずweb.xmlに次のcontext-paramを設定し、JSF参照実装により外部JavaScriptリソースが生成されないようにします。これは、JavaScriptリソースへの参照が適切にエンコードされないという、JSF参照実装における問題を回避するためです。

    <context-param>
        <param-name>com.sun.faces.externalizeJavaScript</param-name>
        <param-value>false</param-value>
    </context-param>
    

59.3.5 Oracle ADFのガイドライン

Oracle ADFのガイドラインは次のとおりです。

  • Oracle ADFタスク・フローをポートレット化する場合は、そのタスク・フローをページにリージョンとしてドロップし、ページを実行することによって、そのタスク・フローを使用できることを確認します。これにより、ポートレット化の前にタスク・フローが正しく実行されることを確認できます。

  • ADF Facesダイアログ・フレームワークはサポートされていません。アプリケーションに二次的なブラウザ・ウィンドウを表示するボタンやアイコンが含まれる場合は、アプリケーションがポートレットとして実行される場合、新しいウィンドウのコンテンツは適切に表示されません。したがって、アプリケーションのポートレット化を計画する場合は、これらのコンポーネントの使用を避ける必要があります。二次的なウィンドウを表示するコンポーネントの例は次のとおりです。

    • <tr:inputDate>

    • <tr:inputColor>

    • <tr:popup>

    • <af:commandButton>useWindow属性

  • コンポーザ・コンポーネントを含むページのポートレット化はサポートされていません。

  • <af.fileDownloadActionListener>コンポーネントはサポートされていません。

  • prepareModelを処理するOracle ADFコンポーネント/コードは冪等性を持つ必要があります。prepareModelフェーズ中に実行されるコードは、基礎のデータまたはビジネス・ロジックに影響を与えずに、再実行可能であることが必要です。ポートレット環境での実行時に、prepareModelは、完全なJSFライフ・サイクル中に2回コールされます。これに対して、通常のWebアプリケーション内で実行される場合、コールは1回です。

    この違いは、Oracle JSF Portlet Bridgeが、JSFを1つではなく2つのリクエストで実行するためです。JSFポートレット・ブリッジは、すべてのJSFリクエストがレンダリング・フェーズの前にリダイレクトされるかのように実装されます。この方法の結果、JSF restoreViewフェーズは、リクエストが最初に送信されるときと、レンダリングのリクエストが受信されるときの両方でコールされます。

  • ページ・パラメータ内を除き、モデル・コードからリクエスト・パラメータをアクセスまたは参照しないでください。よりきれいなMVC2実装であることに加えて、このガイドラインに従うことで、そのようなアーティファクトがポートレットとして公開された場合に問題を回避します。通常のJSFアーティファクトが1つのリクエストで全ライフサイクルを実行するのに対して、Oracle JSF Portlet Bridgeは、すべてのJSFリクエストがレンダリング・フェーズの前にリダイレクトされるかのように、これらのアーティファクトを2つのリクエストで実行します。

    この2フェーズ・モデルにより、レンダリングの前に、送信されたパラメータのクリアが可能になります。そのようなクリアは元のクライアントにまで伝えられるため、このリクエストにはブックマークを付けることができます。その結果、リクエスト・パラメータはレンダリング・フェーズ中には存在しません。先に説明したように、このレンダリング・フェーズでprepareModelが再び起動されます。したがって、このフェーズ・ハンドラでは、リクエスト・パラメータに対する参照は失敗します。次のフラグメントのようなコードは避けてください。

    <invokeAction id="doExecuteWithParams" 
                  Binds="ExecuteWithParams" 
                  Refresh="prepareModel" 
                  RefreshCondition="${param.id != null}"
    />
    
    <invokeAction id="doExecuteWithParams" 
                  Binds="ExecuteWithParams" 
                  Refresh="renderModel" 
                  RefreshCondition="${param.id != null}"
    />
    
  • prepareModelフェーズで、ページ・パラメータを参照しないでください。この問題は、リクエスト・パラメータについて説明した同じ問題に関連しています。一般に、ページ・パラメータはリクエスト・パラメータによって決まり、restoreViewフェーズ中に評価されます。このフェーズが、ポートレットのレンダリング中にもう一度コールされ、リクエスト・パラメータがないと、失敗します。かわりに、JSFの実行フェーズからレンダリング・フェーズへの遷移の前に、ページ・パラメータ値に対する依存性をモデルに移動します。

  • Trinidadコンポーネントのみ(<tr: >タグのみ)を含むアプリケーションをポートレット化する場合は、次のライブラリをプロジェクトに手動で追加する必要があります。

    • jdeveloper\modules\oracle.adf.view_11.1.1\adf-richclient-api-11.jar

    • jdeveloper\modules\oracle.adf.view_11.1.1\adf-richclient-impl-11.jar

    これにより、プロデューサに対して生成された、スタイルシートにあるアイコンへのURLが正しくエンコードされるようになります。

  • ポートレットはネーミング・コンテナであるため、ADF Facesのクライアント側APIを使用してコンポーネントを検索する場合は、特に注意が必要です。コンポーネントIDの例を次に示します。

    • 通常のWebアプリケーションとして実行する場合: id="demoTemplate:popup"

    • ポートレット・プロデューサ・アプリケーションとして実行する場合: id="__ns12345678:demoTemplate:popup"

    特に注意が必要な点を次に示します。

    • AdfPage.PAGE.findComponentByAbsoluteId() APIの使用は避けます。かわりにgetSource()メソッドおよびfindComponent()メソッドを使用します。次に例を示します。

      <trh:script text="
      function showPopup(event) {
          event.cancel();
          // var popup =
          //  AdfPage.PAGE.findComponentByAbsoluteId("demoTemplate:popup");
          var source = event.getSource();
          var popup = source.findComponent("popup");
          popup.show({align:"after_end", alignId:"button"});
      }
      "/>
      
    • clientIdに対しては、絶対パス(:で始まるもの)ではなく、相対パスを使用します。次に例を示します。

      <af:showPopupBehavior popupId="demoTemplate:iteratorpop"
                  triggerType="mouseHover"/>
      

      次は使用しません。

      <af:showPopupBehavior popupId=":demoTemplate:iteratorpop"
                  triggerType="mouseHover"/>
      
    • 詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Webユーザー・インタフェース開発者ガイド』のネーミング・コンテナの使用に関する必要な知識に関する項を参照してください。

  • コンテキスト・イベントをトリガーするOracle ADFタスク・フローをポートレット化する場合、Oracle JSF Portlet BridgeはJSR 286イベントを作成してコンテキスト・イベントをラップします。JSR 286イベントのペイロードの一部は、ラップされたコンテキスト・イベントのペイロードで、シリアライズされています。このラップされたコンテキスト・イベントを配信する場合、コンテキスト・イベントのペイロードをコンシューマでデシリアライズしてから、コンテキスト・イベントをコンシューマ・アプリケーションに転送する必要があります。イベントをデシリアライズするには、ペイロードのクラスがコンシューマのほか、プロデューサでも使用可能である必要があります。この条件は、オリジナルのペイロードがJavaランタイム環境のクラス(java.lang.Stringなど)の場合、自動的に適合します。

  • Oracle ADFタスク・フローにADFmイベントが含まれており、portlet.xmlファイルで対応するポートレット・イベントが宣言されていない場合、Oracle JSF Portlet Bridgeでそれらの宣言されていないイベントを発生させることができます。

    宣言されていないイベントを発生させるには、ポートレット化されたタスク・フローに対して、次のとおりコンテナ実行時オプションを設定します。

    <portlet id="Application5untitled1jspx1_1">
       ...
       <container-runtime-option>
          <name>oracle.portlet.bridge.adf.raiseUndeclaredContextualEvents</name>
          <value>true</value>
       </container-runtime-option>
       ...
    </portlet>
    

    このオプションをtrueに設定することは、発生したADFmイベントがすべてポートレット・イベントとして転送されることを意味します。このオプションが提供されていないか、falseに設定されている場合は、対応するポートレット・イベントが宣言されているイベントのみが転送されます。

    宣言されていないポートレット・イベントが、ポートレット・バインディングからADFmイベントとして自動的に転送されるようにすることもできます。

    ポートレット・バインディングで、raiseUndeclaredContextualEvent属性をtrueに設定します。次に例を示します。

    <portlet id="Application5untitled1jspx1_1"
             portletInstance="/oracle/adf/portlet/WsrpPortletProducer4/ap/
                   Application5untitled1jspx_2943bd23_012e_1000_8004_0aa7c0849010"
             class="oracle.adf.model.portlet.binding.PortletBinding"
             retainPortletHeader="false"
             listenForAutoDeliveredPortletEvents="true"
             listenForAutoDeliveredParameterChanges="true"
             raiseUndeclaredContextualEvents="true"
             xmlns="http://xmlns.oracle.com/portlet/bindings"/>
    

    このオプションをtrueに設定することは、ポートレット・イベントが受信されると、ポートレット・バインディングでイベントが宣言されていない場合でも、対応するADFmイベントが発生することを意味します。ADFmイベントの名前は、ポートレット・イベントのQNameから直接取得されます。これは、Oracle JSF Portlet Bridgeから発生したADFmイベントに、リモート・アプリケーションでのイベント発生時に使用されたものと同じ名前を付けるためです。

  • デフォルトでは、ポートレット化されたページまたはタスク・フローのURLは、コンシューマ・アプリケーションによってプロキシ処理されるよう、エンコードされます。状況によっては、これらのURLをエンコードしないようにする場合があります。たとえば、コンテンツ配信ネットワークからJavaScriptライブラリを要求する場合や、ローカルで構成されたHTTPプロキシを使用するため、ユーザーのブラウザから直接リソースにアクセスする場合です。URLエンコードを回避するには、エンコード用にOracle JSF Portlet Bridgeに渡されるURLで、_xEncodeUrlパラメータをfalseに設定します。

    たとえば、Googleマップを含むインライン・フレームは通常、ユーザーのブラウザのHTTPプロキシ設定を使用して、外部のmaps.google.comサーバーにアクセスする必要があります。コンポーネントがポートレットとして公開されたときに、正しい動作が可能になるADFマークアップは、次のようになります。

    <af:inlineFrame id="if1"
                    shortDesc="Location of office"
                    source="http://maps.google.com/maps?q=RG6+1RA&amp;
                            output=embed&amp;_xEncodeUrl=false"/>
    

    注意:

    このパラメータを使用して、プロデューサ・サーバーにあるリソースにアクセスしないでください。これらのリソースには、ポートレット・クライアントのプロキシを使用してアクセスする必要があります。


59.4 実行時作成スキンのJSFポートレット・プロデューサ・アプリケーションへのコピー

WebCenter Portalアプリケーションでは、リソース・マネージャを使用して実行時にスキンを作成できます。作成時に、JSFポートレットを含んだページでは、レンダリングに関する問題が発生することがあります。これは、WebCenter Portalアプリケーションで使用されるスキンが、タスク・フローをレンダリングするリモート・アプリケーションでは利用できないためです。

この問題に対処するには、タスク・フローがポートレット化された時点で、実行時に作成したスキンをポートレット・プロデューサ・アプリケーションにコピーする必要があります。

実行時に作成したスキンをポートレット・プロデューサ・アプリケーションにコピーする手順は、次のとおりです。

  1. スキンをFrameworkアプリケーションからEARファイルにエクスポートします。

    実行方法の詳細は、第17.4.1項「リソース・マネージャを使用してリソースをダウンロードする方法」を参照してください。

  2. エクスポートされたスキンを、共有ライブラリ(JARファイル)として再パッケージ化します。

    1. 次のようにtransport.marファイルを抽出します。

      $ jar xvf myskin.ear
      inflated: transport.mar
      
    2. 次のようにメタデータ・ファイルを抽出します。

      $ jar xvf transport.mar
      inflated: oracle/webcenter/siteresources/.../Skin.css
      inflated: oracle/webcenter/siteresources/.../generic-site-resources.xml
      ...
      
    3. メタデータ・ファイルの中からgeneric-site-resources.xmlファイルを見つけて表示します。通常、このファイルは次のようなディレクトリに存在します。

      oracle/webcenter/siteresources/scopedMD/scopeGUID/generic-site-resources.xml
      

      このファイルには、次の例のようにエクスポートされたスキンについて記述するセクションがあります。

      <resourceType name="skin" ...>
        <resource displayName="MySkin"
           metadataFile="/oracle/webcenter/siteresources/.../Skin.css" ...>
          <customAttributes>
            <customAttribute name="skinId"
               value="gsr616d879d_99e0_4bd9_8c10_98e7ea272a6a.desktop" .../>
            <customAttribute name="skinFamily"
               value="gsr616d879d_99e0_4bd9_8c10_98e7ea272a6a" ...>
            <customAttribute name="skinExtends"
               Value="webcenter-fusion-internal.desktop" .../>
          </customAttributes>
        </resource>
      </resourceType>
      
    4. generic-site-resources.xmlの次の情報に注意してください。

      • skinId (たとえば、gsr616d879d_99e0_4bd9_8c10_98e7ea272a6a.desktop)

      • skinFamily (たとえば、gsr616d879d_99e0_4bd9_8c10_98e7ea272a6a)

      • skinExtends (たとえば、webcenter-fusion-internal.desktop)

    5. 次のようにJARファイルのディレクトリ構造を構築します。

      $ mkdir META-INF
      
    6. 次のようにMETA-INFディレクトリ内にSkin.cssファイルをコピーします。

      $ cp oracle/webcenter/siteresources/.../Skin.css META-INF
      
    7. 次のように、META-INFディレクトリの下にtrinidad-skins.xmlという新しいファイルを作成します。

      $ edit META-INF/trinidad-skins.xml
      
    8. この新しく作成されたtrinidad-skins.xmlファイルに次のXMLを追加します。

      <?xml version="1.0" encoding="ISO-8859-1"?>
      <skins xmlns="http://myfaces.apache.org/trinidad/skin">
        <skin>
          <style-sheet-name>Skin.css</style-sheet-name>
          <id>skinId</id>
          <family>skinFamily</family>
          <extends>skinExtends</extends>
          <render-kit-id>org.apache.myfaces.trinidad.desktop</render-kit-id>
        </skin>
      </skins>
      

      skinIdskinFamilyおよびskinExtendsは、前述した値です。

    9. 次のように、JARファイルをパッケージ化します。

      $ jar cvf myskin.jar META-INF
      adding: META-INF/trinidad-skins.xml(in = 359) (out= 171)(deflated 52%)
      adding: META-INF/Skin.css(in = 5560) (out= 1413)(deflated 74%)
      

      JARファイルには、Skin.cssおよびtrinidad-skins.xmlの2つのファイルを含める必要があります。

  3. 新しく作成されたmyskin.jarファイルをポートレット・プロデューサ・アプリケーションにコピーします。

    最も簡単な方法は、ポートレット・プロデューサのWebアプリケーションのWEB-INF/libディレクトリに、ファイルをコピーすることです。