プライマリ・コンテンツに移動
Oracle® Fusion Middleware Oracle JDeveloperによるWebCenter Portalアセットとカスタム・コンポーネントの開発
12c (12.2.1.2.0)
E82735-01
目次へ移動
目次

前
次

17 カスタム・ページレットの作成

この章では、アダプティブ・ページレットのスクリプティング・フレームワークを使用する方法、ページレットおよびリソースのセキュリティ設定を構成してユーザーの認証を管理する方法、カスタムWebインジェクタおよびパーサーを使用して実行時にページレット機能を変更する方法、デバッグ用の拡張ロギング・トレースにアクセスする方法など、ページレット・プロデューサを使用したページレットの構築について詳しく説明します。

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

17.1 アダプティブ・ページレットのスクリプティング・フレームワークの使用

アダプティブ・ページレットのスクリプティング・フレームワークは、サービスをCSPページレットとプロキシされたページに提供するクライアント側JavaScriptライブラリです。この項では、スクリプティング・フレームワークを使用して動的機能をページレットに実装する方法について説明します。

注意:

CSP (およびアダプティブ・ページレットのスクリプティング・フレームワーク)は、WCIとその前のPlumtree Portalにのみ適用されます。WebCenter PortalではCSPはサポートされません。

この項には次のトピックが含まれます:

クラスとメソッドの完全リストについては、JSPortlet APIのドキュメントを参照してください。アダプティブ・ページレットの詳細は、「アダプティブ・ページレットの開発に関する必知事項」を参照してください。

17.1.1 構造化されたHTTPレスポンスの処理方法

この項では、アダプティブ・ページレットのスクリプティング・フレームワークを、通常XMLとしてエンコードされる、構造化されたHTTPのクライアント側レスポンス・ハンドラとして使用する方法について説明します。

ごく一部のユーザー・インタフェースのみを変更する必要がある場合、一部のHTTPリクエストに応じて大量のHTMLを返すのは多くの場合費用がかかり非効率的な可能性があります。これは、より複雑なユーザー・インタフェースに特に当てはまります。このような場合は、レスポンスをXMLでエンコードできます。クライアント側レスポンス・ハンドラはXMLを解析し、そのレスポンスに基づいてユーザー・インタフェースを更新(またはその他の処理を実行)できます。構造化されたレスポンス設計パターンを使用して、HTTPリクエストの作成後にユーザー・インタフェースの小領域を再描画するか、単純なHTTP/URIタイプのWebサービスにページレットからアクセスします。次のコード例 (structuredresponse_portlet.html) では、新しいサイトの選択からRSSフィードにアクセスします。

<!-- jsxml includes -->
<a id="imgServerHref" href="/images/plumtree" style="display:none"></a>
<script type="text/javascript"
src="/images/plumtree/common/private/js/PTLoader.js"></script>
<script type="text/javascript">
var oImgServer =new Object();
oImgServer.location =document.getElementById('imgServerHref').href;
var imageServerURL =document.getElementById('imgServerHref').href;
var imageServerConnectionURL =oImgServer.location;
new PTLoader(imageServerURL, imageServerConnectionURL).include('jsxml','en');
</script>

<!-- jscontrols includes -->
<link rel="stylesheet" type="text/css" href="/portal-remote-server/js/jscontrols/styles/css/PTMenu.css"/>
<link rel="stylesheet" type="text/css" href="/portal-remote-server/js/jscontrols/styles/css/PTRichTextEditor.css"/>
<script type="text/javascript" src="/portal-remote-server/js/jscontrols/strings/PTControls-en.js"></script>
<script type="text/javascript" src="/portal-remote-server/js/jscontrols/PTControls.js"></script>

<!-- Inline JS helper functions -->
-->

<script defer type="text/javascript" id="structured-response-portlet-A-script">
// Function that gets the RSS XML feed found at the specified url
getRSSFeed =function(url)
 {
//First clear out any existing rows in the table
 channelTable.clearRows();

 //Force the transformer to fix up the url
 var oURL =new Object();
 oURL.location =url;

 //Do the http get
 var get =new PTHTTPGETRequest(oURL.location, handleRSSResponse);
 get.invoke();
 }

//Function that handles the RSS XML response and updates the table based on the RSS items
handleRSSResponse =function(response)
 {
//Get the rss xml
 var xml =response.responseText;
 if (!xml ││xml.indexOf('<?xml') ==-1) {return; }

//Parse into a dom, and get the channel node
 var xmlDOM =new PTXMLParser(xml);
 var rssNode =xmlDOM.selectSingleNode('rss');
 var channelNode =rssNode.selectSingleNode('channel');

 //Get the channel title and set the status bar text in the table
 var channelTitle =channelNode.selectSingleNode('title').getNodeValue();
 channelTable.statusBarText ='<b>Loaded Channel</b>: ' +channelTitle;

 //Get channel item nodes
 var itemNodes =channelNode.selectNodes('item');
 
//Build table rows
 channelTable.rows =new Array();
 for (var i=0; i<itemNodes.length; i++)
 {
var itemNode =itemNodes[i];

 //Get channel item properties
 var itemTitle =itemNode.selectSingleNode('title').getNodeValue();
 var itemLink =itemNode.selectSingleNode('link').getNodeValue();
 var itemDescription =itemNode.selectSingleNode('description').getNodeValue();
 if (itemNode.selectSingleNode('author'))
 var itemAuthor =itemNode.selectSingleNode('author').getNodeValue();
 if (itemNode.selectSingleNode('category'))
 var itemCategory =itemNode.selectSingleNode('category').getNodeValue();
 if (itemNode.selectSingleNode('pubDate'))
 var itemPubDate =itemNode.selectSingleNode('pubDate').getNodeValue();

 //Create a row and add it to the table
 var row =new PTRow();
 row.parent =channelTable;
 row.id =i;
 row.uid =i;
 row.previewText =itemDescription;
 row.link =itemLink;
 row.columnValues[0] =new PTTextColumnValue(itemTitle);
 row.columnValues[1] =new PTTextColumnValue(itemCategory);
 row.columnValues[2] =new PTTextColumnValue(itemAuthor);
 row.columnValues[3] =new PTTextColumnValue(itemPubDate);
 channelTable.rows[channelTable.rows.length] =row;
 }

//Redraw the table
 channelTable.draw();
 }
</script>

<b>Select RSS Feed:</b>
<a href="#" onclick="getRSSFeed('http://www.wired.com/news/feeds/rss2/0,2610,,00.xml'); return false;">Wired News</a>
<a href="#" onclick="getRSSFeed('http://news.com.com/2547-1_3-0-5.xml'); return false;">CNET News.com</a>
<a href="#" onclick="getRSSFeed('http://partners.userland.com/nytRss/nytHomepage.xml'); return false;">NY Times</a>
<br><br>

<!-- Set up a table control to display channel items -->
<div id="channelTableContainer"></div>
<script defer type="text/javascript">
 var channelTable =new PTTableControl();
 channelTable.locale ='en_US';
 channelTable.objName ='channelTable';
 channelTable.container ='channelTableContainer';
 channelTable.baseURL ='/imageserver/plumtree/common/private/portal-remote-server/js/jscontrols/1/';
 channelTable.statusBarText ='No RSS Feed Selected';
 channelTable.rowDetailAction =new PTJavaScriptAction('window.open(\'${ROW.link}\');');
 channelTable.columns[0] =new PTColumn();
 channelTable.columns[0].name ='Title';
 channelTable.columns[0].width ='40%';
 channelTable.columns[1] =new PTColumn();
 channelTable.columns[1].name ='Category';
 channelTable.columns[1].width ='20%';
 channelTable.columns[2] =new PTColumn();
 channelTable.columns[2].name ='Author';
 channelTable.columns[2].width ='20%';
 channelTable.columns[3] =new PTColumn();
 channelTable.columns[3].name ='Publication Date';
 channelTable.columns[3].width ='20%';
 channelTable.areColumnsResizable =true;
 channelTable.clientSortEnabled =true;
 channelTable.scrollHeight =250;
 channelTable.init();
 channelTable.draw();
</script>
</div>

17.1.2 イベント通知の使用方法

この項では、アダプティブ・ページレットのスクリプティング・フレームワークにより、ページレットがどのように、その他のページレットによって生成されたページレベルのイベントとカスタム・イベントの両方に応答できるようになるかを説明します。

スクリプティング・フレームワーク内のメソッドregisterForWindowEventおよびregisterOnceForWindowEventは、ページレベルのイベントにアクセスできるページレットを指定します。完全なリストは、「スクリプティング・フレームワークでページレベルのイベントを使用する方法」を参照してください。これらのイベントの通知を登録するには、イベントの名前と、イベント発生時にコールする必要のあるメソッドの名前を渡します。ページレベルのイベントが発生すると、JavaScriptイベント・オブジェクトが引数としてイベント・ハンドラに渡されます。スクリプティング・フレームワークでは、ページレットはraiseEventおよびregisterForEventを使用してカスタム・イベントを発生させ、応答することができます。ブロードキャスト/リスナー・デザイン・パターンは、セッション・プリファレンスを指定して通知サービスを使用する重要な例です。ユーザーはアイテムを選択するか、「ブロードキャスト」ページレットで別のアクションを実行できます。これによって、その他の「リスナー」ページレットのコンテンツが再作成されます。次の例では、ブロードキャスト・ページレットによって、テキスト・ボックスに数字を入力できるフォームが表示されます。

図17-1 ブロードキャスト・ポートレット

図17-1の説明が続きます
「図17-1 ブロードキャスト・ポートレット」の説明

ユーザーがテキスト・ボックスに数値を入力すると、リスナー・ページレットの値が変更されます。最初のリスナー・ページレットには、ブロードキャスト・ページレットに入力した数値の平方根が表示されます。

図17-2 リスナー1のポートレット

図17-2の説明が続きます
「図17-2 リスナー1のポートレット」の説明

2番目のリスナー・ページレットには、ブロードキャスト・ページレットに入力した数値の立方根が表示されます。

図17-3 リスナー2のポートレット

図17-3の説明が続きます
「図17-3 リスナー2のポートレット」の説明

次の手順では、ページレットがどのように機能するのかについてまとめています。

  • ロード時に、各リスナー・ページレットは固有のインスタンス・メソッド(registerForEvent)をコールし、onBroadcastUpdateタイプのイベントを登録します。

  • Enter numberテキスト・ボックスに発生するonkeyupイベントごとに、ブロードキャスト・ページレットはセッション・プリファレンスをこのテキスト・ボックスに入力された値に設定し、その固有のインスタンス・メソッド(raiseEvent)をコールしてonBroadcastUpdateタイプのイベントを生成します。

  • onBroadcastUpdateイベントが発生したり、ページが再ロードされた場合は、各リスナー・ページレットがブロードキャスト・ページレットによって設定されたセッション・プリファレンスを取得し、プリファレンスの値に基づいて表示する新しい値を計算します。

ブロードキャスト・ページレット

<div style="padding:10px;" align="center">
<p><b>Enter number:</b>
&nbsp;<input type="text" style="font-size:22px;font-weight:bold;text-align:center;"
id="broadcast_prefName" value="4" size="7" onkeyup="broadcast_setPrefs(this.value)"></p>
<br>
</div>

<script type="text/javascript">
function broadcast_setPrefs(val)
{
 var prefName ='broadcastNumber';
 var prefValue =val;
 PTPortlet.setSessionPref(prefName,prefValue);
 var broadcastPortlet =PTPortlet.getPortletByGUID('{D9DFF3F4-EAE7-5478-0F4C-2DBD94444000}');

 if (!broadcastPortlet)
 {
broadcast_debug('Could not locate PTPortlet object which corresponds to <b>Broadcast Portlet</b> on page.');
 return;
 }
broadcast_debug('<b>Broadcast Portlet</b> raising onBroadcastUpdate event.');
 broadcastPortlet.raiseEvent('onBroadcastUpdate',false);
}
function broadcast_debug(str)
{
 if (window.PTDebugUtil) 
{
PTDebugUtil.debug(str); 
}
}
</script>

リスナー・ページレット#1

<div style="padding:10px;" align="center">
<p><b>Square root:</b>
<div style="height:21px;border:2px solid black;padding:2px;overflow:visible;font-size:14px;"id="listener1-swatch">
</div>
</div>

<script>
function listener1_update()
{
 var broadcastNumber =parseFloat(PTPortlet.getSessionPref('broadcastNumber'));
 if (isNaN(broadcastNumber))
 {
listener1_error('<b>Listener-1 Portlet</b> cannot parse number from session pref broadcastNumber');
 return;
 }

listener1_debug('<b>Listener-1 Portlet</b> computing square root of ' +broadcastNumber);
 var swatch =document.getElementById('listener1-swatch');
 swatch.innerHTML =Math.sqrt(broadcastNumber);
}

function listener1_debug(str)
{
 if (window.PTDebugUtil) 
{
PTDebugUtil.debug(str); 
}
}

function listener1_error(str)
{
 if (window.PTDebugUtil) 
{
PTDebugUtil.error(str); 
}
}

function listener1_getPortlet()
{
 var portletGUID ='{D9DFF3F4-EAE7-5478-0F4C-2DBDB4F4A000}';
 var listener1Portlet =PTPortlet.getPortletByGUID(portletGUID);
 return listener1Portlet;
}

var listener1Portlet =listener1_getPortlet();
if (listener1Portlet)
{
 listener1Portlet.registerForEvent('onBroadcastUpdate','listener1_update');
 listener1_debug('<b>Listener-1 Portlet</b> registered refreshOnEvent for event onBroadcastUpdate');
 listener1Portlet.registerForEvent('onload','listener1_update');
}

</script>

リスナー・ページレット#2

<div style="padding:10px;" align="center">
<p><b>Cube root:</b>
<div style="height:21px;border:2px solid black;padding:2px;overflow:visible;font-size:14px;"id="listener2-swatch">
</div>
</div>

<script>
var listener2_oneThird =(1/3);
function listener2_update()
{
 var broadcastNumber =parseFloat(PTPortlet.getSessionPref('broadcastNumber'));
 if (isNaN(broadcastNumber))
 {
listener2_error('<b>Listener-2 Portlet</b> cannot parse number from session pref broadcastNumber');
 return;
 }

listener2_debug('<b>Listener-2 Portlet</b> computing square root of ' +broadcastNumber);
 var swatch =document.getElementById('listener2-swatch');
 swatch.innerHTML =Math.pow(broadcastNumber,listener2_oneThird);
}

function listener2_debug(str)
{
 if (window.PTDebugUtil) 
{
PTDebugUtil.debug(str); 
}
}

function listener2_error(str)
{
 if (window.PTDebugUtil) 
{
PTDebugUtil.error(str); 
}
}

function listener2_getPortlet()
{
 var portletGUID ='{D9DFF3F4-EAE7-5478-0F4C-2DBDCA1C7000}';
 var listener2Portlet =PTPortlet.getPortletByGUID(portletGUID);
 return listener2Portlet;
}

var listener2Portlet =listener2_getPortlet();
if (listener2Portlet)
{
 listener2Portlet.registerForEvent('onBroadcastUpdate','listener2_update');
 listener2_debug('<b>Listener-2 Portlet</b> registered refreshOnEvent for event onBroadcastUpdate');
 listener2Portlet.registerForEvent('onload','listener2_update');
}

</script>

17.1.2.1 スクリプティング・フレームワークでページレベルのイベントを使用する方法

スクリプティング・フレームワークでは、次のページレベルのイベントに自動的にアクセスできます。

表17-1 ページレベルのイベント

イベント トリガー時期:

onload

ブラウザがページをロードした直後

onbeforeunload

ページがアンロードされる(ブラウザ・ウィンドウが閉じるか別の場所に移動する)前

onunload

ページがアンロードされる(ブラウザ・ウィンドウが閉じるか別の場所に移動する)直前

onactivate

ページがアクティブ要素として設定された(フォーカスを取得した)とき

onbeforeactivate

ページがアクティブ要素として設定される(フォーカスを取得する)直前

ondeactivate

アクティブ要素が現在のページから親ドキュメントの別のページに変更されたとき

onfocus

ページがフォーカスを取得したとき

onblur

ページがフォーカスを喪失したとき

oncontrolselect

ユーザーがページのコントロールをまさに選択するとき

onresize

ページのサイズをまさに変更するとき

onresizestart

ユーザーがコントロールの選択でページのディメンションの変更を開始したとき

onresizeend

ユーザーがコントロールの選択でページのディメンションの変更を終了したとき

onhelp

ブラウザがアクティブ・ウィンドウになっている状態でユーザーが[F1]キーを押したとき

onerror

ページのロード中にエラーが発生したとき

onafterprint

関連するドキュメントが印刷されたまたは印刷プレビューされた直後

17.1.3 インプレース・リフレッシュの使用方法

この項では、ページレットで、スクリプティング・フレームワークを使用してインプレース・リフレッシュを実装することによって、ページをリフレッシュすることなく内部コンテンツを再ロードする方法について説明します。

ページレットの多くは時間に影響を受けるデータを表示します。場合によっては、ユーザーはページの残りの部分を変更またはリフレッシュすることなく、ページレット内のリンク間を移動できる必要があります。ページレット・コンテンツは、コマンドを使用する、リフレッシュ・アクションをイベントに関連付ける (refreshOnEvent)、または設定した間隔でリフレッシュするようにページレットをプログラムする(setRefreshInterval)ことでリフレッシュできます。スクリプティング・フレームワークにはまた、ページレットを開閉するためのメソッドも用意されています。次の単純な例では、リフレッシュ・ページレットに「ポートレットのリフレッシュ」ボタンが表示されます。このボタンをクリックすると、ページレットに表示される日時が更新されます。

図17-4 ポートレットのリフレッシュ

図17-4の説明が続きます
「図17-4 ポートレットのリフレッシュ」の説明

インプレース更新は、ページレット・オブジェクト・インスタンスに対してrefresh()メソッドをコールすることにより、実行されます。リフレッシュ時には、新しいURLがページレット内に表示されるように設定することもできます。(タイトル・バーはリフレッシュ時に変更できません。)

<div style="padding:10px;" align="center">
<p><button onclick="refresh_portlet()">Refresh Portlet</button></p>
<p><b>Current time is:</b><br> <span id="refreshTimeSpan"></span></p>
</div>

<script type="text/javascript"> 
function refresh_portlet()
{
var refreshPortlet =PTPortlet.getPortletByID($PORTLET_ID$);
if (!refreshPortlet)
 {
refresh_debug('Could not locate PTPortlet object which corresponds to <b>Refresh Portlet</b> on page.');
 return;
 }
refresh_debug('<b>Refresh Portlet</b> calling refresh() method.');
refreshPortlet.refresh();
}

function refresh_debug(str)
{
if (window.PTDebugUtil) 
{
PTDebugUtil.debug(str); 
}
}

var t =new Date();
document.getElementById('refreshTimeSpan').innerHTML =t;
</script>

17.1.4 セッション・プリファレンスの使用方法

この項では、ブラウザレベルの変数が同一ページ上にない場合でも、その変数を格納してページレット間で共有する方法について説明します。たとえば、1つのページレットにユーザーが入力した値は、別のユーザーが取得できます。スクリプティング・フレームワークは仲介として機能するため、セッション・プリファレンスを使用すると、すべてのページレットで共通セッションに格納されているすべての値にアクセスできます。

ページレットはプリファレンスを使用して相互に通信できますが、プリファレンスにアクセスするには通常、データベースへのラウンドトリップが必要です。セッション・プリファレンスは、クライアント・ブラウザ内でユーザーのセッションの設定を保存および共有する手段を提供します。「マスター/ディテール」デザイン・パターンは、セッション・プリファレンスの最も基本的な使用方法です。このデザイン・パターンでは、2つのページレットの間で制御と表示が分割されます。たとえば、「マスター」ページレットではデータをリスト形式で要約し、「ディテール」ページレットではユーザーの選択に応じてデータ・アイテムごとにディテールを表示することができます。次の例では、マスター・ページレットによって、テキスト・ボックスに色コードを入力できるフォームが表示されます。

ユーザーが色コードをテキスト・ボックスに入力すると、ディテール・ページレットに表示されている色が変更されます。

マスター・ページレットの「色の入力」テキスト・ボックスでonkeyupが発生するたびに、次の手順が実行されます。

  1. マスター・ページレットのテキスト・ボックスの現在値を使用してセッション・プリファレンスが設定されます。

  2. マスター・ページレットからディテール・ページレットの更新メソッドがコールされます。

  3. ディテール・ページレットにより、セッション・プリファレンスから色の値が取得されます。

  4. ディテール・ページレットの色見本領域が再描画され、新しい色の値が反映されます。

注意:

共有のセッション・プリファレンスは、ページレット・プロデューサ・コンソール内のページレットの「プリファレンス」ページから名前で指定する必要があります。指定しないと、プリファレンスはページレットに送信されません。

アダプティブ・ページレットのスクリプティング・フレームワークには、ページレット間の関係を解除し、共通のイベント・インタフェースを使用して通信するための簡単な方法が用意されています。

注意:

次の例は極度に簡略化されたもので、マスター・ページレットからディテール・ページレットのJavaScriptメソッドが直接コールされます。マスター・ページレットで、ディテール・ページレットが同一ページ上に実際に存在することを確認するためのなんらかの処置を講じないかぎり、マスターからディテールに対してコールすると、エラーが発生する可能性があります。

マスター・ページレット

<div style="padding:10px;" align="center">
<p><b>Enter color:</b> &nbsp;
<input type="text" style="font-size:22px;font-weight:bold;text-align:center;" id="master_prefName"
value="#FFFFFF" size="8" onkeyup="master_setPrefs(this.value)"></p><br>
</div>

<script type="text/javascript">
function master_setPrefs(val)
{
var prefName ='masterColor';
var prefValue =val;
PTPortlet.setSessionPref(prefName,prefValue);

master_debug('<b>Master Portlet</b> called PTPortlet.setSessionPref(\'masterColor\',\'' +prefValue +'\').');

if (window.detail_update)
 {
master_debug('<b>Master Portlet</b> calling detail_update().');
 detail_update();
 }
else
 {
master_debug('Could not locate portlet <b>Detail Portlet</b> on page.');
 }
}
function master_debug(str)
{
if (window.PTDebugUtil) 
{
PTDebugUtil.debug(str); 
}
}
</script>

ディテール・ページレット

<div style="padding:10px;" align="center">
<p><b>Color swatch</b> &nbsp;
<div style="width:100px;height:100px;border:2px solid black;padding:2px;"id="detail-swatch"></div>
<script>
function detail_update()
{
var color =PTPortlet.getSessionPref('masterColor');
detail_debug('<b>Detail Portlet</b> received value="' +color +'" for PTPortlet.getSessionPref(\'masterColor\')');

var swatch =document.getElementById('detail-swatch');
if (swatch)
 {
swatch.innerHTML ='<div style="background-color:' +color +';width:100%;height:100%;"></div>';
 }
else
 {
detail_debug('<b>Detail Portlet</b> cannot find \'detail-swatch\' DIV element.');
 }
}

function detail_debug(str)
{
if (window.PTDebugUtil) 
{
PTDebugUtil.debug(str); 
}
}
</script>

17.1.5 アダプティブ・ページレットの開発に関する必知事項

次のヒントは、アダプティブ・ページレットのスクリプティング・フレームワークを使用するほとんどのページレットに当てはまります。

  • すべてのフォームと関数に一意の名前を使用します。一意の名前と値の形成にページレットのGUIDを使用し、ページ上の他のコードと名前の衝突が発生しないようにします。

  • すべてのURLをプロキシします。コール元のページと異なるホスト/ポートを持つURLに対するリクエストを作成することはできません。JavaScriptを通じてリクエストされるURLはすべてプロキシする必要があります。

  • アダプティブ・ページレットのスクリプティング・フレームワークを使用している場合は、サポートをチェックします。コンポーネントが存在するかどうかを判断するコードを組み込むことをお薦めします。理想的には、ページレットでいずれの状況も処理できる必要があります。最も簡単な解決方法は、スクリプティング・フレームワークがサポートされていない場合にユーザーに警告を行うIf文を備えたコードを優先することです。

    <script>
    if (PTPortlet ==null) 
    {
    if (document.PCC ==null) 
    {
    alert("This pagelet only works in portals that support the JSPortlet API .
    The pagelet will be displayed with severely reduced
     functionality. Contact your Administrator.");
     }
    }
    else 
    {
    [scripting code here]
     }
    </script>
    
  • ウィンドウが閉じるときに、ページレットによって開かれたポップアップ・ウィンドウをすべて閉じます。onunloadイベントを使用してポップアップ・ウィンドウを閉じる場合に、スクリプティング・フレームワークを使用できます。

  • 必要なすべてのJavaScriptを前もってページに追加しておきます。innerHTMLプロパティを使用してページに追加されたスクリプト・ブロック/インクルードは、ブラウザで処理されない場合があります。

    • Microsoft Internet Explorer: スクリプト・タグにdefer(遅延)属性を追加します。

    • Netscape: RegExpを使用してレスポンスを解析し、スクリプトを見つけて評価します。

  • JavaScript HTTPとプロキシされたHTTPで同じ認証資格証明を使用する必要があります。JavaScriptで仲介されたHTTPリクエストからは、ゲートウェイ処理された正常なHTTPリクエストの作成時と同じ認証トークン(cookie)が送信されます。

17.2 実行時のページレット機能の変更

この項では、カスタム・インジェクタおよびパーサーを使用して、実行時にページレット機能を変更する方法について説明します。

この項には次のトピックが含まれます:

17.2.1 Webインジェクタの使用方法

Webインジェクタは、プロキシされているリソース・ページの指定の場所にコンテンツを挿入します。コンテンツには、HTML、CSS、JavaScriptおよびページレット宣言などのテキストを指定できます。ページから不要なコンテンツを削除するために空のインジェクタを使用することもできます。インジェクタをOpenSocialリソース用に作成することはできません。単純なHTMLコンテンツの注入についてはユース・ケースが限られていますが、ページレットのHTMLマークアップを直接変更するJavaScriptを注入することもできます。Webインジェクタの作成の詳細は、「Webインジェクタの作成」を参照してください。

17.2.2 カスタム・パーサーの使用方法

カスタム・パーサーを使用すると、コンテンツを解析し、URLを検索するための組込みのロジックを補足したり変更できます。組込みのパーサーがURLの識別やURLとしてリライトしてはいけないセクションの識別に失敗した場合は、カスタム・パーサーを使用してデフォルトの動作を変更できます。パーサーは、WSRPまたはOracle PDK-Javaポートレット・プロデューサ用に、あるいはOpenSocialガジェット・プロデューサ用に作成することはできません。カスタム・パーサーの作成の詳細は、「カスタム・パーサーの作成」を参照してください。

17.3 ページレットのデバッグ

この項では、ページレットのデバッグに拡張ロギング・トレースを使用する方法について説明します。ロギングは、ページレット・プロデューサ・コンソールの「設定」セクションで構成され、ここで、ページレット・プロデューサの各コンポーネントについて様々なレベルのロギングを定義できます。詳細は、「ページレット・プロデューサ設定の構成」を参照してください。

この項には次のトピックが含まれます:

17.3.1 HTTPリクエストおよびレスポンスの表示方法

ページレット・プロデューサによって送受信されたHTTPリクエストおよびレスポンスを表示するには、ロギング設定ページで「HTTP」コンポーネントを「最も詳細」に設定します。「ページレット・プロデューサによって受信されたHTTPリクエスト」、「ページレット・プロデューサによって送信されたHTTPレスポンス」、「ページレット・プロデューサによって送信されたHTTPリクエスト」および「ページレット・プロデューサによって受信されたHTTPレスポンス」のトレースは、テスト環境から取得したものです。

ページレット・プロデューサによって受信されたHTTPリクエスト

URL: http://example.com:7001/pagelets/bidwiki/includes/js/ajax.js
METHOD: GET
SESSION ID: GdYGNJzMhxy1CJBMVTX8xTNq32GmLXYNY9VqFBcdprFnhcyQtzdp!1377086614!1305769149498
HEADERS: 
Host: example.com
 Connection: keep-alive
 Referer: http://example.com:7001/pagelets/bidwiki/dashboard.action
 User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.205 Safari/534.16
 Accept: */*
Accept-Encoding: gzip,deflate,sdch
 Accept-Language: en-US,en;q=0.8,ru;q=0.6,it;q=0.4
 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
 If-None-Match: W/"736-1124953206000"
 If-Modified-Since: Thu, 25 Aug 2012 07:00:06 GMT
COOKIES: 
JSESSIONID: GdYGNJzMhxy1CJBMVTX8xTNq32GmLXYNY9VqFBcdprFnhcyQtzdp!1377086614

ページレット・プロデューサによって送信されたHTTPレスポンス

URL: http://example.com:7001/pagelets/bidwiki/styles/main-action.css
Response Code: 200
Reason: 
HEADERS: 
Date: Thu, 19 May 2011 01:39:14 GMT
 Content-Type: text/css;charset=UTF-8
 Server: Apache-Coyote/1.1
BODY: 
.sidebar {
/*background-image: url(http://example.com:7001/pagelets/bidwiki/download/ resources/leftnav_bg.jpg);*/
 /*background-repeat: repeat-y;*/
 background-color: #F0F0F0;
 /*border-bottom:1px solid #F0F0F0;*/
} ...

ページレット・プロデューサによって送信されたHTTPリクエスト

URL: http://xmlns.oracle.com/includes/js/ajax.js
METHOD: GET
HEADERS: 
CSP-Ensemble-REST-API: http://example.com:7001/pagelets
 X-Client-IP: example.com
 User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.205 Safari/534.16
 CSP-Session-Username: weblogic
 Accept-Language: en-US,en;q=0.8,ru;q=0.6,it;q=0.4
 CSP-Gateway-Type: Proxy
 PT-Proxy-Passes: 1
 If-Modified-Since: Thu, 25 Aug 2012 07:00:06 GMT
 CSP-Protocol-Version: 1.4
 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
 Accept-Encoding: gzip,deflate,sdch
 Referer: http://example.com:7001/pagelets/bidwiki/dashboard.action
 If-None-Match: W/"736-1124953206000"
 Accept: */*
CSP-Aggregation-Mode: Single
 PT-Proxy-instance0: {DECBB085-D891-72CF-2B75-005E7FE20000}
 CSP-Gateway-Specific-Config: PT-User-Name=weblogic,PT-Guest-User=0,...

ページレット・プロデューサによって受信されたHTTPレスポンス

Original URI: http://xmlns.oracle.com/styles/main-action.css
Effective URI: http://xmlns.oracle.com/styles/main-action.css
Status Code: 200
Reason: OK
Version: HTTP/1.1
HEADERS: 
Content-Type: text/css;charset=UTF-8
 Content-Length: 29178
 Server: Apache-Coyote/1.1
 Date: Thu, 19 May 2011 01:39:14 GMT
TRAILERS: 
BODY: 
body, p, td, table, tr, .bodytext, .stepfield {
font-family: Verdana, arial, sans-serif;
 font-size: 11px;
 line-height: 16px;
 color: #000000;
 font-weight: normal;
}

17.3.2 変換コンテンツの表示方法

変換の前後にページレット・プロデューサによってプロキシされたコンテンツを表示するには、ロギング設定ページで「変換」コンポーネントを「最も詳細」に設定します。これらのトレースの目的は、変換の様々な段階でレスポンス・コンテンツをログに記録して、それらを比較したり、異なる変換の結果を表示できるようにすることです。次の各例のトレース例は、テスト環境から取得したものです。

例: 未変換のマークアップ

Original request: URL: http://example.com:7001/pagelets/bidwiki/styles/main-action.css
METHOD: GET
SESSION ID: GdYGNJzMhxy1CJBMVTX8xTNq32GmLXYNY9VqFBcdprFnhcyQtzdp!1377086614!1305769149498
HEADERS: 
Host: example.com:7001
 Connection: keep-alive
 Referer: http://example.com:7001/pagelets/bidwiki/dashboard.action
 User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.205 Safari/534.16
 Accept: text/css,*/*;q=0.1
 Accept-Encoding: gzip,deflate,sdch
 Accept-Language: en-US,en;q=0.8,ru;q=0.6,it;q=0.4
 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
COOKIES: 
JSESSIONID: GdYGNJzMhxy1CJBMVTX8xTNq32GmLXYNY9VqFBcdprFnhcyQtzdp!1377086614
 
Untransformed content: 
body, p, td, table, tr, .bodytext, .stepfield {
font-family: Verdana, arial, sans-serif;
 font-size: 11px;
 line-height: 16px;
 color: #000000;
 font-weight: normal;
}

例: 変換済のマークアップ(トランスフォーマ・クラスによって変換)

Transformed by: class com.plumtree.server.impl.portlet.transformers.CSSTurboParser
 Original request: URL: http://example.com:7001/pagelets/bidwiki/styles/main-action.css
METHOD: GET
SESSION ID: GdYGNJzMhxy1CJBMVTX8xTNq32GmLXYNY9VqFBcdprFnhcyQtzdp!1377086614!1305769149498
HEADERS: 
Host: 10.148.118.211:7001
 Connection: keep-alive
 Referer: http://example.com:7001/pagelets/bidwiki/dashboard.action
 User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.205 Safari/534.16
 Accept: text/css,*/*;q=0.1
 Accept-Encoding: gzip,deflate,sdch
 Accept-Language: en-US,en;q=0.8,ru;q=0.6,it;q=0.4
 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
COOKIES: 
JSESSIONID: GdYGNJzMhxy1CJBMVTX8xTNq32GmLXYNY9VqFBcdprFnhcyQtzdp!1377086614
 
Transformed content: 
body, p, td, table, tr, .bodytext, .stepfield {
font-family: Verdana, arial, sans-serif;
 font-size: 11px;
 line-height: 16px;
 color: #000000;
 font-weight: normal;
}