WebSphere Portalは、異なる種類のエンタープライズ・アプリケーションとコンテンツを集約し、統合して、単一の統一されたアプリケーション・エクスペリエンスをエンド・ユーザーに提供します。ベンダーはWebSphere Portalを使用して、一般的なアプリケーションを形成するパッケージ済みポートレットを開発してきました。これには、ERP、CRM、ホスト・アプリケーション、およびクライアント/サーバー・アプリケーションなどが含まれます。
ポータルが登場する前は、新しいエンタープライズ・アプリケーションは、システム内の情報を参照する機能を個々のウィンドウ・インスタンスでユーザーに提供する、クライアント/サーバー・アプリケーションとして開発されていました。ユーザー・セッションと入力された情報は、各ウィンドウが保持しています。ポータルの領域では、これらのウィンドウはそれぞれ異なるポートレットに相当します。各ポートレットは、複数のポータル・ページに置かれることがあります。このため、ユーザーがマルチタスクや情報参照のためにアプリケーション間を移動すると、ユーザーのアプリケーション固有の情報が失われる可能性があります。
この記事で使用するビジネス・シナリオは、コール・センター・アプリケーションに基づいています。コール・センターでは、顧客サービス担当者(つまり、ポータル・ユーザー)は、情報を参照したり、データを入力したりするために、アプリケーション固有のコンテキストおよびデータを維持したままポータル・ページ間を移動する機能が必要です。
たとえば、ポータル・ユーザーは次のようにポータルにアクセスします。
- あるページでカスタマー情報を入力する。
- 他のポータル・ページに移動する(ポートレットからWeb、ホスト・アプリケーション、クライアント/サーバー・アプリケーションなどへ)。
- 最初の画面に戻る。
ここでの目標は、オリジナル・ポートレット(手順1)に入力されたデータを透過的に保存し、ユーザーが他のポータル・ページ間を行き来する間、そのデータを維持することです。
このシナリオに沿って説明するために、メイン・ページのCall Center AppでWebクリッピング・ポートレットを使用し、レガシーStruts Webアプリケーションをクリップします。また、標準でインストールされているページを使用して、ページ・ナビゲーションをシミュレートします。
データを保存して取得する(維持する)最も一般的な方法は、CookieとJavaScriptを使用することです。この方法では、クライアント・サイドでプロセスが実行されるため、ブラウザーがフォームの送信(form submit)を行う必要がありません
この記事で取り上げる方法では、簡単なJavaScript手法を活用してフォームの送信を強制的に実行するため、バックエンド・アプリケーションがフォーム・データをセッション・オブジェクトに入れて保持することができます。フォームを透過的に送信するために、BODYタグのunload()イベントを使用しました。しかし、ポートレットの標準として、どのポートレット・ビューにもHTMLタグまたはBODYタグは含まれないため、テーマのDefault.jspにunload()イベントを追加する必要があります。
unloadイベントでは、フォームの送信を強制することにより、バックエンド・アプリケーションがフォームの要素を読み取り、フォーム・データを維持できるようにします。
参照用に、サンプルのレガシー・アプリケーションのWARファイルとDefault.jspのコードが、ダウンロード・ファイルとして提供されています。
サンプルのビジネス・シナリオを開発するには:
- バックエンド・アプリケーションをセットアップします。
サンプル・コードInci2.warをダウンロードし、ローカルのWebSphere Application Server 6.0にデプロイします。このアプリケーションは、制御をページに返すシンプル・アクション・クラスです。このサンプルでは、フォーム・データの保持をApache Strutsフレームワークによって管理するために、struts-config.xmlでフォームbeanをセッションに設定したStrutsアプリケーションを使用しました。
リスト1. バックエンド・アプリケーションのstruts-config.xmlファイルとJavaソース・ファイル<action path="/customerRequestAction" type="inci.resources.customerRequestAction" name="customerRequestBean" validate="false" input="/customerRequest.jsp" scope="session"> <forward name="create" path="customerRequest.jsp" contextRelative="true" redirect="false" /> </action> Action class of the web app simply returns control back. package inci.resources; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts.action.Action; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; public class customerRequestAction extends Action { public ActionForward execute (ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { customerRequestForm loginForm = (customerRequestForm) form; System.out.println("Loginaction"); return (mapping.findForward("create")); } }
- 次のurlを使用して、バックエンド・アプリケーションにアクセスできることを確認します。
http://localhost:9080/Inci/customerRequest.jsp
- WebSphere Portalの管理コンソールで、図1に示すようにバックエンドのWebアプリケーションをクリップします。
Webクリッピングは、WebSphere Portal V5.xの組み込み機能です。Webクリッピング・エディターを使用して、Webページ全体またはその一部をクリップできます。ページまたはその一部をクリップした後、任意のポータル・ページに配置できるポートレットがエディターによって作成されます。Webクリッピング・ポートレットを図1に示します。
図1.バックエンドWebアプリケーションのクリップ
- ポータル・ページを作成し、前の手順で作成したWebクリッピング・ポートレットを添付します。
- 追加のポータル・ページを作成し、任意のポートレットを添付します。これらのページは、Webクリッピング・ポートレットがあるページからユーザーが他へ移動するときに使用されます。
あらかじめ用意されているサンプル・ページを使用するか、WebSphere Portalの管理コンソールから新しいページを作成します。たとえば、マイ・ポータルにSwitchという名前の新しいページを作成します。 - 使用するテーマのDefault.jspに次のJavaScript関数を追加することにより、フォーム送信機能を実装します。
リスト2.テーマのDefault.jspに追加するJavaScript関数function formSave(formName, act){ if(window.document.activeElement != "[object]" && window.document.activeElement != null){ // window.document.activeElement returns the name of the object clicked, // we will be using this to capture the link/page user clicked to // navigate after submitting the form. if (!stopSubmits) { stopSubmits = true; // We are using stopSubmits as a Boolean variable to stop the form // submission if user is intentionally performing other actions in the form. var form = document.forms[formName]; form.all.tags("input").item("hiddenOperation").value = act; //hiddenOperation is a hidden field used to differentiate different actions // at the server side just in case needed. form.elements["url"].value = window.document.activeElement; form.submit(); window.location.href = form.elements["url"].value; // above statement redirects to url clicked after form submit. } } }
ポータル・テーマはすべてのポータル・ページにわたって共通なので、ポートレットを含むページだけでフォームの送信が発生するようにしなければなりません。これを行うために、次の条件ステートメントを追加します。if document.forms['wpsFormtoSave'] != null
複数のポートレットからのデータを保存する必要がある場合は、フォームをループすることによってこれを実現できます。
ユーザーが送信ボタンをクリックすることで意図的にフォームの保存を試みたときに、このスクリプトが起動されないようにするには、if (!stopSubmits)ボタンのアクションをチェックします。
任意のページでのクリックによるユーザーのアクションをリダイレクトすることによって、Webページを透過的に送信できますが、ユーザーはクリックしたページへ移動するものと思っています。これを実現するには、クリックされたページをJavaScriptメソッドのwindow.document.activeElementを使用して読み取り、これをフォーム変数urlに格納します。そして、ページ送信の完了後、この値を読み取ります。
response.sendRedirect("<url>")を使用してサーバー・サイドでurlをリダイレクトする方法も試みましたが、ポータル・ページ全体がポートレット・ウィンドウで開かれる結果となりました。このため、クライアント・サイドでurlをリダイレクトする方法を選びました。代替シナリオ
状況によっては、バックエンド・アプリケーションをクリップせずに、独自に開発されたポートレット・アプリケーションを使用したいこともあります。このようなケースでは、actionPerfomedイベントを使用してデータをポートレット・アプリケーションに送信できます。この場合、上記のデフォルト・テーマのコードを実装する代わりに、次に示すポートレット・アプリケーションの受信アクションを利用できます。
リスト3. テーマのDefault.jspに追加するJavaScript関数<body marginwidth="0" marginheight="0" <%=bidiDirAttr%> onUnload="if (document.forms['<portletAPI:encodeNamespace value="wpsFormtoSave"/>'] != null ) formSave(['<portletAPI:encodeNamespace value="wpsFormtoSave"/>');"> function formSave(formName, act){ if(window.document.activeElement != "[object]" && window.document.activeElement != null){ if (!stopSubmits) { stopSubmits = true; var form = document.forms[formName]; form.all.tags("input").item("operation").value = act; form.elements["url"].value = window.document.activeElement; document.<portletAPI:encodeNamespace value="wpsFormtoSave"/>.action = "<portletAPI:createURI> <portletAPI:URIAction name='formSaveAction'/> </portletAPI:createURL>"; //encoding namespace and creating an action to trigger // actionPerformed() event is required if you use custom portlets // instead of clipped applications. form.submit(); window.location.href = form.elements["url"].value; } } }
- Default.jspのBODYタグに、Javascriptイベントのunloadを追加します。
<body marginwidth="0" marginheight="0" <%=bidiDirAttr%> onUnload="if (document.forms['wpsFormtoSave'] != null ) formSave('wpsFormtoSave');"> - シナリオのテストを準備するために、ポータル・ページをロードします。次のポートレットが表示されます。
図2.完成したポートレット
それでは、ビジネス・シナリオの紹介で示した次のユーザー・ステップに従い、シナリオをテストします。
- 任意のページで情報を入力します。
- 他のポータル・ページに移動します。
- 最初のページに戻ります。前に入力したデータが保持されているはずです。
この手順を次の画面ショットで示します。それぞれの図は、ユーザーがフォームへのデータ入力を開始する、データ入力途中でユーザーが他のページへ移動する、ユーザーが元のページに戻り、前に入力したデータがすべて保持されていることを確認する、という3つの状況を示しています。
図3.任意のページでユーザーがカスタマー情報の入力を開始する

図4.ユーザーが他のポータル・ページへ移動する

図5.ユーザーが最初のデータ入力用のフォーム・ポートレット・ページに戻る

この記事では、ユーザーがポータル・ページ間を移動したときに、データを維持したまま、フォームをレガシー・バックエンド・アプリケーションに透過的に送信する手法について解説しました。また、クリップしたレガシー・アプリケーションの代わりにポートレット・アプリケーションを使用する状況で用いられる同様の手法についても解説しました。
| 内容 | ファイル名 | サイズ | ダウンロード形式 |
|---|---|---|---|
| Code samples | samples-persisting.zip | 6.6 MB | FTP |
学ぶために
- developerWorks Japan: Lotus: Lotusの日本の技術情報サイトです
- developerWorks: Lotus(US) : Lotusの英語の技術情報サイトです
- developerWorks WebSphere Portal zone:ポータルとポートレットの開発に役に立つ、幅広く多様な技術情報を提供しています。
- Page-to-page communication between legacy Web pages and portlets:レガシーなWeb (非ポータル)ページと、JSR 168ポートレットもしくはIBM APIポートレットとの間で情報を受け渡しする方法をご紹介しています。
- Page-to-page communication between JSR 168 portlets in WebSphere Portal V5.1.0.1:あるページ上のJSR 168ポートレットが、cross-page wiringを使用して他のページ上のJSR 168ポートレットに情報を受け渡しできます。
- Page-to-page communication between portlets:WebSphere Portal V4.2.1とV5.0.2のどちらでも使える2つのテクニック-事前に定義されたデータの静的リンクを機能させる方法と、受信ポートレットに届いたユーザーの入力データをリンクする-をご紹介しています。
- IBM Redbook: IBM Rational Application Developer V6 Portlet Application Development and Portlet tools:基本的な情報ポートレットを作成する為に正常なアプリケーションを使用した、開発者向け環境が内蔵されたポータルのツールはこちらをご参照ください。Rational Application Developer環境と、組み込みのPortal toolsを使用してポートレットを作成するための基本的な情報です。
- Portlet development guide:WebSphere Portal V5.xで、ポートレットの開発を始めるのに役立つご案内はこちらからご参照ください。
- WebSphere Portal production documentation:WebSphere PortalのInfoCenters、リリース・ノート、およびreadmesを含む現在あるすべての製品資料をご参照いただけます。
製品や技術を入手するために
- Rational Application Developer V6:developerWorksから試用版ソフトウェアをダウンロードできます。Portal toolsと、プロトタイプの開発に利用できるポータルのテストランタイム環境を含んでいます。含んでいます。
Kris Vishwanathan is an IT Architect who has been with IBM since 2003. He worked as a senior developer and architect for IBM Systems and Technology Group before joining IBM Software Services for Lotus at the end of 2004. He has been part of the delivery team implementing WebSphere Portal and Web Content Management (WCM) solutions. In addition to architecting solutions for clients, he also sets up portal production environments involving portal clustering, Tivoli Access Manager, LDAP, user registry configurations, and portlet development using JSR168, JSF, IBM API, and WCM API. He is an IBM Certified WebSphere Portal System Administrator and Solution Developer.