以下、図面を参照しながら発明の実施形態を説明する。
本実施形態にかかるWebサーバ、Webブラウザは、いずれも計算機上でソフトウェア(Webサーバプログラム、Webブラウザプログラム)を実行させることで実現することができる。この場合に、必要に応じてOSやドライバソフト、あるいは通信インターフェース装置、外部記憶装置、入出力装置といったハードウェアが搭載あるいは接続される。また、ユーザへの情報呈示/ユーザからの情報入力のために、グラフィカル・ユーザー・インターフェース(GUI)を用いる必要がある。
本実施形態では、World Wide Webシステムでの通信は、HTTPプロトコルに従って行なわれる。HTTPプロトコルに関してはRFC1945に示されているHTTP1.0もしくはRFC2616に示されているHTTP1.1を用いて説明する。
本実施形態では、図1に示すように、Webサーバ(簡単にサーバと呼ぶことがある)とWebクライアント(簡単にクライアントと呼ぶ)とが、LANを介して接続され、クライアントからのリクエストがサーバに転送され、サーバは転送されたリクエストに対するレスポンスをクライアントに転送することで、ユーザへの情報の呈示・情報の入力が行なわれる場合について説明する。
また、サーバとクライアント(Webブラウザ)との間の通信プロトコルには、HTTPプロトコルを用いる場合について説明する。
なお、図1では、クライアントとサーバとの間がLANで接続されている場合を示したが、バックボーンネットワークは、上記LANである場合に限らず、インターネットやWAN(Wide Area Network)、公衆回線、PHSや携帯電話を用いた無線ネットワークなど、回線の種類を問わず適用可能である。
図1は、本実施形態に係るコンピュータ・ネットワークシステムの構成例を示したものである。図1において、Webサーバとしての計算機1(サーバ1)は、LAN3を介してWebクライアントとしての計算機2(クライアント2)と接続する。計算機1は、Webアプリケーションプログラムを実行することにより、Webアプリケーション11の機能を備えるWebサーバである。また、計算機2(クライアント2)は、Webブラウザプログラムを実行することにより、Webブラウザ(以下、簡単にブラウザと呼ぶ)12の機能を備えるWebクライアントである。サーバ1は、クライアント2からのリクエストを受信すると、レスポンスを生成して返信する。
図1では、1つのサーバ1に対し、1つのクライアントが対応するが、勿論複数のサーバに対し複数のクライアントが対応する場合であっても適用可能である。この場合、各クライアントは、クッキー(Cookie)などを用いたセッションによって識別され、サーバはセッション毎に、返送するレスポンスを動的に生成する。
(クライアントとサーバとの間の一般的な処理手順(1))
まず、図1に示す構成のクライアント・サーバシステムにおけるサーバ・クライアント間の通信の処理手順について説明する。
図2は、サーバ1のWebアプリケーション11の機能構成例を示したものである。クライアント2のブラウザ12上に、例えば図3に示すようなユーザインタフェースのWebページを表示するために、図3のWebページを構成するラベルや、テキスト入力フィールド、ボタンなどの複数のGUI部品のそれぞれ対応する複数のUIコンポーネントが階層的に接続されている。
図3に示すWebページに対応するHTMLテキストは、複数のエレメントからなる階層構造を有し、各エレメントはタグにより表されている。図2に示すような複数のUIコンポーネントからなる階層構造(これを「コンポーネントツリー」と呼ぶ)は、図3に示すWebページのHTMLテキストの階層構造と同一である。なお、図2は、UIコンポーネントを組み合わせてユーザインタフェースを作成するためのJavaServer Faces(JSF)に基づくものである。
図2において、サーバ1のWebアプリケーション11は、複数のUIコンポーネント101b〜101mを含む階層構造を有するUIコンポーネントツリー101aを有する。また、サーバ1は、Webアプリケーション11で、Webページを生成する際に用いる値を記憶するためのデータ保持部102を備えている。データ保持部102は、サーバ1が持つメモリに、Webページを生成する際に用いる値を記憶する。
UIコンポーネント(HtmlForm)101cは、HTMLのタグ<form>を出力し、UIコンポーネント(HtmlPanelGrid)101d、101g及び101kは、表示の整形を行なうHTMLのタグ<table>、<tr>、<td>を出力し、UIコンポーネント(HtmlOutputLabel)101e、101h及び101lは、タグのない通常の文字列を出力し、UIコンポーネント(HtmlCommandLink)101fは、「<a href=url>文字列</a>」という文字列とそのリンク先を出力し、UIコンポーネント(HtmlInputText)101iは、入力テキストフィールド「<input type=”text”>」を出力し、UIコンポーネント(HtmlCommandButton)101jは、サブミットボタン「<input type=”submit”>」を出力し、UIコンポーネント(HtmlSelectManyListbox)101mは、複数個の要素を表示可能なリストボックス「<select>要素</select>」を出力する。
ユーザインタフェース上の各GUI部品には識別子が与えられ、当該GUI部品を出力する当該GUI部品に対応するUIコンポーネントは、当該GUI部品と同一の識別子をもつ。
各UIコンポーネントは、クライアント2から送信された、パラメータのないGETリクエストを受信すると、各UIコンポーネントが再帰的に階層構造に従ってHTMLタグを出力することでHTMLレスポンスを生成し返信する。その際、必要に応じてUIコンポーネントはデータ保持部102から、当該データ保持部101で記憶されたデータを取得し、HTMLタグを生成する。
図2ではHtmlSelectManyListbox101mが、データ保持部102から“2005/02/18”というデータを取得し、selectタグを生成する。
JSFの場合、データ保持部102は、バッキングビーンと呼ばれる。このバッキングビーンと、そこに記憶されているデータを用いてHTMLのエレメントを生成するUIコンポーネントとの関連付けは、Webアプリケーションプログラムに記述されている。
図2は、Webのプレゼンテーション層に対応したコンポーネントツリーを示しているが、上記データ保持部102とコンポーネントの関連付けをはじめとしたWebアプリケーションのアプリケーション・ロジックやコンポーネントツリーの開発にはタグを用いるのが一般的である。
JSFを用いたWebアプリケーションプログラムも、JSPタグによって記述される。図2の各UIコンポーネントに対応するタグクラスとTLD(Tag Library Description)によってJSPタグが定義されている。Webアプリケーション11は、各JSPタグに対応する各エレメントからなる所望の階層構造を有する。サーバ1が、Webアプリケーションプログラムを実行することにより、サーバ1上に、図2に示したようなUIコンポーネントツリー101aが形成される。また、JSPタグのプロパティに、アプリケーション・ロジックを記述することで、上記バッキングビーンとUIコンポーネントの関連付けなどが行える。
図3は、図2にUIコンポーネントツリー101aにより生成されたHTMLテキストを用いて、クライアント2のブラウザ12により表示されるWebページの一例を示したものである。
クライアントのブラウザ12は、例えば、「http://www.hello.co.jp/world.jsp」というURLに対してリクエストを出し、サーバ1のWebアプリケーション11が、このリクエストを受けて、レスポンスを返信し、クライアント2のブラウザ12がこのレスポンスを受信し、描画を行なって、図3に示すようなWebページ201が表示される。
図3において、「休暇申請」という文字列201eは、図2のHtmlOutputLabel101eによって生成された文字列である。「出張申請」という文字列201fは、図2のHtmlCommandLink101fによって生成されたリンク文字列である。「日付」という文字列201hは、図2のHtmlOutputLabel101hによって生成された文字列である。入力テキストボックス201iは、図2のHtmlInputText101iによって生成されたものである。「取得」と表示されているサブミットボタン201jは、図2のHtmlCommandButton101jで生成されたサブミットボタンである。「取得済み」という文字列201lは、図2のHtmlOutputLabel101lによって生成された文字列である。「2005/02/18」が唯一の要素となっているリストボックス201mは、図2のHtmlSelectManyListbox101mによって生成されたリストボックスである。
図3のWebページの描画に利用されるHTMLテキストは、図2の各UIコンポーネントが出力したHTMLタグによって構成されている。ただし、図2及び図3の例ではリストボックス201mに対応するHtmlSelectManyListbox101mのみが、対応するJSPタグにバッキングビーンズを関連付けることでHTMLタグを動的に生成し、それ以外のHTMLタグは、Webアプリケーション11を開発する際に、対応するJSPタグに予め指定した静的な文字列から生成されたものである。
Webアプリケーション11の処理は、次に示すような6つのフェーズに分類される。即ち、(1)UIコンポーネントツリーの生成・復元(Restore Viewフェーズ)、(2)リクエスト値の適用(Apply Request Valuesフェーズ)、(3)入力値の検証(Process Validationsフェーズ)、(4)モデルの更新(Update Model Valuesフェーズ)、(5)アプリケーションロジックの呼び出し(Invoke Applicationフェーズ)、(6)レスポンスのレンダリング(Render Responseフェーズ)。
(1)Restore Viewフェーズは、JSPタグから図2に示したようなUIコンポーネントとUIコンポーネントツリーを生成・復元するフェーズである。(2)Apply Request Valuesフェーズは、クライアントからのリクエスト中のパラメータから、各UIコンポーネントに対応する識別子をキーに、値を取得するフェーズである。(3)Process Validationsフェーズは、クライアント側で入力された入力値のチェックである。(4)Update Model Valuesフェーズは、(3)Process Validationsフェーズで検証した値をバッキングビーンズで保存させるフェーズである。(5)Invoke Applicationフェーズは、データベースの呼び出しや、各フェーズでキューされたイベントを実行するフェーズである。(6)Render Responseフェーズは、各UIコンポーネントが、それぞれに対応するHTMLタグを生成し、レスポンスを返した後、UIコンポーネントを保存するフェーズである。
上記6つのフェーズからなる処理フロー(ライフサイクル)を図6に示す。
ステップS1は上記(1)Restore Viewフェーズに対応し、ステップS3は上記(2)Apply Request Valuesフェーズに対応し、ステップS4は上記(3)Process Validationsフェーズに対応し、ステップS5は上記(4)Update Model Valuesフェーズに対応し、ステップS6は上記(5)Invoke Applicationフェーズに対応し、ステップ7は上記(6)Render Responseフェーズに対応する。
クライアント2のブラウザ12からリクエスト(Hypertext transfer protocol (HTTP)のGETリクエスト、ポストリクエスト)を受け付けると、ステップS1の(1)Restore Viewフェーズが始まる。
ブラウザ12から、例えば、「http://www.hello.co.jp/world.jsp」というURLで指定されたリソース(図3に示すようなWebページ)へのリクエスト(例えば、GETリクエスト)を初めて受け取ると、ステップS1の(1)Restore Viewフェーズが始まり、コンポーネントツリー101aが生成される。この後、ステップS2へ進む。この初めてのリクエストの場合、当該リクエストには、クライント側で入力された入力値や、ボタン押下により発生するイベントなど(リクエスト・パラメータ)が含まれていないため、ステップS2から、ステップS7の(6)Render Responseフェーズへ以降する。
ステップS7では、各UIコンポーネントが、それぞれに対応するHTMLタグを生成し、図3に示すようなWebページに対応するHTMLテキストを生成する。そして、このHTMLテキストを含むレスポンスをクライアント2に返した後、各UIコンポーネントを保存する。
ブラウザ12は、サーバ1からの上記レスポンスを受けて、当該レスポンスに含まれるHTMLテキストを用いて、図3に示したようなWebページを表示する。
ブラウザ12から、図3に示すようなWebページ上の入力テキストフィールド201iに、ユーザにより入力された入力値を含む(リクエスト・パラメータを含む)リクエスト(例えば、POSTリクエスト)を受け付けた場合、ステップS1の(1)Restore Viewフェーズでは、レスポンス時に保存してあったUIコンポーネントツリー101aを復元し、ステップS2へ進む。POSTリクエストには、リクエスト・パラメータが含まれているので、ステップS2からステップS3へ進む。
この場合、受け取ったリクエストの「body」エレメントには、入力テキストフィールド201iというGUI部品の識別子(当該GUI部品に対応するUIコンポーネントの識別子)と、当該識別子に対応するUIコンポーネントに渡すべき入力値と、イベントとが含まれている。そこで、ステップS3では、当該リクエストに含まれている入力値やイベントを、当該入力値やイベントを受け取るべきUIコンポーネントが取得し、当該UIコンポーネントは、この取得した入力値やイベントを一時保存する。その後、ステップS4の(3)Process Validationsフェーズへ移行する。
ステップS4では、ステップS3でUIコンポーネントに保持された(適用された)入力値のデータ型などを検証し、エラーが出なかった場合には、ステップS5へ進む。なお、エラーが出た場合には、その後の値の更新処理は行われない。
ステップS5の(4)Update Model Valuesフェーズでは、UIコンポーネントで一時保持された値をデータ保持部102で記憶する。その後、ステップS6へ進む。
ステップS6の(5)Invoke Applicationフェーズは、例えば、ボタンの押下といったイベントに対してロジックを呼び出し、このロジックの結果によって、次の画面遷移先を決定する。その後、ステップS7へ進む。
ステップS7の(6)Render Responseフェーズは、各UIコンポーネントが、次の画面を表示するためのHTMLタグを生成し、レスポンスをクライアント2へ返す。
なお、図6のステップS4の(3)Process Validationsフェーズの処理は本発明の要旨ではないので説明は省略する。JSFに関する詳細は、「JavaServer FacesによるWebアプリケーション開発」(川崎克己著、秀和システム、2004、ISBN-4798008303)に記載されている。
図4は、図2に示した機能を有するWebアプリケーション11を備えたサーバ1と、ブラウザ12を備えたクライアント2との間でHTTPを用いた通信を行い、クライアント2のブラウザ12で、Webページを表示し、このWebページ上にユーザにより入力された値で、サーバ1のデータ保持部102を更新するための手順と、更新後のデータ保持部102に記憶された値で、表示の更新を行うための手順について説明する。
まず、クライアント2のブラウザ12から、「http://www.hello.co.jp/world.jsp」というURLを指定した、パラメタなしのGETリクエストを送信する(ステップP1)。該リクエストを受信したサーバ1のWebアプリケーション11は、図6のステップS1の(1)Restore Viewフェーズで、各UIコンポーネントを生成または復元し、ステップS7の(6)Render Responseフェーズで、各UIコンポーネントがHTMLタグを出力し、レスポンスを生成する。このとき、図2のHtmlSelectManyListbox101mは、データ保持部102から文字列「2005/02/18」を取得し(ステップP2a)、リストボックスを動的に生成する(ステップP2)。
Webアプリケーション11は、ステップP2で生成されたレスポンスをブラウザ12に返信する(ステップP3)。ブラウザ12は、レスポンスを受信し、画面を描画することで、図3に示したようなWebページを表示する。
図3に示したような表示状態のときに、クライアント2のユーザは、図3の入力テキストフィールド201iに文字列「2005/03/04」を入力し、サブミットボタン21jを押下すると、ブラウザ12が「http://www.hello.co.jp/world.jsp」に対してPOSTリクエストを送信する(ステップP4)。このPOSTリクエストには、入力テキストフィールド201iに対応する識別子「tf1」をキーとし、入力値「2005/03/04」を値(バリュー)とするリクエスト・パラメータ「tf1=2005/03/04」が含まれている。なお、ここで、入力テキストフィールド201iは、図2のHtmlInputText101iが出力するので、この入力テキストフィールド201iは、UIコンポーネントのHtmlInputText101iの識別子「tf1」をもち、この識別子「tf1」が、リクエスト・パラメータのキーとして含まれている。
ステップP5において、POSTリクエストを受信したWebアプリケーション11は、まず、図6のステップS1の(1)Restore Viewフェーズで、各UIコンポーネントを復元し、ステップS2へ進む。当該POSTリクエストには、上記リクエスト・パラメータが含まれているため、ステップS3へ進む。ステップS3の(2)Apply Request Valuesフェーズでは、UIコンポーネントのHtmlInputText101iが、上記リクエストパラメータから、識別子「tf1」をキーに、値「2005/03/04」を取得し、ステップS4へ進む。ステップSS4の処理は、本実施形態の要旨にかかる重要な処理ではないので、説明は省略する。次に、ステップS5へ進む。
ステップS5の(4)Update Model Valuesフェーズでは、HtmlInputText101iは、データ保持部102に、当該取得した値「2005/03/04」を記憶し(ステップP6a)、ステップS6を経由して、ステップS7へ進む。ステップS7の(6)Render Responseフェーズでは、各UIコンポーネントはHTMLタグエレメントを出力し、レスポンスを生成する。このとき、図2のHtmlSelectManyListbox101mは、データ保持部102から、既に記憶されていた文字列「2005/02/18」、及びステップS5で記憶した文字列「2005/03/04」を取得し(ステップP5b)、リストボックスを動的に生成する。
Webアプリケーション11は、ステップP5で生成されたレスポンスを、ブラウザ12に返信する(ステップP6)。ブラウザ12は、レスポンスを受信し、画面を描画することで図5に示したように、Webページが表示される。
図3に示したWebページのリストボックス201mには、文字列「2005/02/18」の1つだけが表示されているが、図5のWebページのリストボックス201mには、2つの文字列「2005/02/18」及び「2005/03/04」が表示されている。
図4のステップP2で、図6のステップS1及びステップS7の(1)Restore Viewフェーズ及び(6)Render Responseフェーズが実行され、図4のステップP5で、図6のステップS1〜ステップS7の6つのフェースが実行される。
このように、図4のステップP4と、ステップP5の(1)Restore Viewフェーズ、(2)Apply Request Valuesフェーズ、(3)Process Validationsフェーズ、(4)Update Model Valuesフェーズの処理により、クライアント2のブラウザ12で表示されているWebページ上への新たなデータの入力に対応して、サーバ1のデータ保持部102に記憶されているデータを更新する(サーバ1をクライアント2に同期させる)。
また、図4のステップP5の(6)Render Responseフェーズと、ステップP6の処理により、更新後のデータ保持部102で保持されているデータと、クライアント2のブラウザにより表示されたWebページ上のリストボックス201mの表示内容とを一致するように表示更新する(クライアント2をサーバ1に同期させる)。
(クライアントとサーバとの間の一般的な処理手順(2))
次に、サーバ1のWebアプリケーション11により、ユーザ・インターフェース(Webページ)上の一部のGUI部品を表示し、残りのGUI部品をクライアントアプリケーションが表示する場合について説明する。
この場合のサーバ1の機能構成例を図7に示し、クライアント2のブラウザ12上の表示例を図8に示す。また、クライアント2が、(例えばサーバ1から取得した)クライアントアプリケーションプログラムを実行することにより、クライアント2が備える機能、すなわち、クライアントアプリケーション301の機能構成例を図9に示す。
図7のWebアプリケーション11の各機能は、図2と同様、サーバ1でWebアプリケーションプログラムを実行することにより実現され、図2と同様に、UIコンポーネントツリー101aを有する。なお、図7において、図2と同一部分には同一符号を付し、異なる部分について説明する。すなわち、図7では、図2のHtmlPanelGrid101gと、その子のUIコンポーネント101h〜101jの代わりに、ブラウザ12上のクライアントアプリケーション301の起動を命令するHTMLタグ(<object>か<embed>など)を出力するUIコンポーネント「クライアントアプリケーション起動」101nが挿入されている。さらに、図7では、後述の図8のクライアントアプリケーション301と通信を行なう通信部103が新たに追加されている。
サーバ制御部106は、サーバ1全体の制御を司る。
クライアントアプリケーション記憶部105には、クライアント2へ渡すクライアントアプリケーションプログラムが記憶されている。
まず、Webアプリケーション11の通信部103を用いて、サーバ1をクライアント2に同期させる場合について、図10を参照して説明する。
クライアント2のユーザが、ブラウザ12に、「http://www.hello.co.jp/world.jsp」というURLへのGETリクエストを送信させる(ステップP11)。リクエストを受信したWebアプリケーション11は、(1)Restore Viewフェーズ及び(6)Render Responseフェーズを実行し(ステップP12)、レスポンスを返す(ステップP13)。このレスポンスには、図7に示すように、クライアントアプリケーションを起動するためのUIコンポーネント101nにより生成されたクライアントアプリケーションの起動命令と、クライアントアプリケーションの保存場所を示す情報を有するHTMLテキストが含まれている。
このレスポンスを受信したブラウザ12は、このHTMLテキストを解釈してユーザインターフェースを描画するとともに(ステップP14)、クライアントアプリケーションの保存場所に対してGETリクエストを送信する(ステップP15)。
クライアントアプリケーション記憶部105は、このGETリクエストを受けて、クライアントアプリケーションのアーカイブを読み出し、これをボディとするレスポンスを返信する(ステップP16)。
レスポンスを受信したブラウザ12により、クライアントアプリケーション301が起動される(ステップP17)。このとき、クライアント1のブラウザ12上に表示されるWebページには、図3と同様に、各GUI部品が表示される。なお、図8において図3と同一部分には同一符号を付し、異なる部分についてのみ説明する。すなわち、図8では、GUI部品201h、201i、201jを含む領域201zが、(図7のUIコンポーネント101nにより出力されたHTMLタグによって起動された)クライアントアプリケーション301により表示されている。
図9において、クライアントアプリケーション301は、図8の領域201z及びGUI部品201h〜201jのそれぞれに対応する複数のコンポーネント301z、301h〜301jからなるコンポーネントツリー301aと、イベントハンドラ301と、通信部302を備えている。
コンポーネントツリー301aは、コンポーネント(JApplet)301zを最上位のノードとし、その子ノードとして、コンポーネント(JLable)301h、コンポーネント(JTextField)301i、コンポーネント(JButton)301jが接続された階層構造を有する。クライアントアプリケーション301が起動されると、コンポーネントツリー301a上の各コンポーネント301z、301h〜301jが、それぞれ、ユーザインタフェース上の領域201z及びGUI部品201h〜201jとして表示される。
一般に、オブジェクト指向言語で開発されたアプリケーションは、コンポーネントツリー301aのように、GUI部品を階層化した構造になっている。
JApplet301zは、図8のGUI部品201h〜201jを表示するための図8の領域201zに対応する。JLabel301hは、図8の「日付」という文字列のGUI部品201iに対応する。JTextField301iは、図8の入力テキストボックス201iに対応する。JButton301jは、図8の「取得」と表示されたサブミットボタン201jに対応する。
クライアントアプリケーション301は、クライアント2の通信部302を介して、サーバ1と通信を行う。イベントハンドラ303は、ここでは、サブミットボタン201jの押下により発生したイベントを処理する。
クライアント2のブラウザ12上で、ユーザが、入力テキストボックス201iに、「2005/03/04」と入力し、「取得」ボタン201jを押下すると、これを検知したJButton301jでイベント(ActionEvent)が発生する(ステップP18)。そのリスナであるイベントハンドラ303が、JTextField301iから上記入力値を取得する。そして、通信部302から、HTTPによる通信、RMIやRPCなどといった分散オブジェク方式による通信、ソケットを介したTCP/IPによる通信などの専用通信を用いて、サーバ1へ、クライアント2での入力値を送信する(ステップP19)。
図7のサーバ1のWebアプリケーション11が、通信部103を備える場合、クライント2から送信されてきた入力値は、この通信部103で受信される(ステップP20)。そして、データ保持部102を受信した入力値で更新するためのメソッドを用いて、当該入力値をデータ保持部102に記憶する(ステップP21)。
以上の処理により、サーバ1をクライアント2に同期させている。
なお、上記のようにしてサーバ1がクライアント2に同期した後、更新されたデータ保持部102の内容を、クライアント2のブラウザ12上に反映させるためには、クライアント2から再度同一URLにリクエストを送信し、図10のステップP11〜ステップP17を行って、Webページのリロードすればよい。
なお、クライアントアプリケーション記憶部105は、必ずしもサーバ1が備えている必要はなく、サーバ1とは別個の装置上に設けられていてもよいし、クライアント1のローカルディスク装置に保存されていても良い。ただし、クライアントアプリケーションがJavaアプレットの場合は、図7のように、サーバ1が当該クライアントアプリケーションを記憶し、サーバ1からクライアント2へダウンロードする必要がある。
次に、サーバ1が、図7に示すように、上記Webアプリケーション11の他に、サーバ制御部106及びデータベース104を備え、上記通信部103ではなく、サーバ制御部106が、クライアント2の通信部302から送信された、図8のWebページ上に入力された入力値を受信する場合について、図11を参照して説明する。
ユーザが、ブラウザ12に「http://www.hello.co.jp/world.jsp」というURLへのGETリクエストを送信させる処理(ステップP11)から、クライアントアプリケーション301が通信部302での専用通信を用いて、ユーザにより入力された入力値を送信する(ステップP19)までは、図10と同様であり、説明は省略する。
図11では、専用通信を用いて、クライアント2から送信された入力値「2005/03/04」は、サーバ制御部106により受信される(ステップP31)。サーバ制御部106は、受信した入力値をデータベース104に記憶するための命令をデータベース104へ出力する(ステップP32)。データベース104は、この命令を受け取ると、当該入力値を記憶する(ステップP33)。
次に、クライアント2のユーザが、ブラウザ12上のリロードボタンを押下するなどして、クライアント2のブラウザ12から、サーバ1のWebアプリケーション11に、GETリクエストが送信される(ステップP34)。リクエストを受信したWebアプリケーション11は、上記6つのフェーズを実行し、そのうちの(5)Invoke Applicationフェーズの処理で、データベース104から、記憶された上記入力値を取得し、この入力値をデータ保持部102に記憶する(ステップP35)。以上の処理により、サーバ1をクライアント2に同期させている。
なお、上記のようにして、サーバ1がクライアント2に同期した後、Webアプリケーション11は、ステップP35の上記6つのフェーズのうち、(6)Render Responseフェーズの処理によって、各UIコンポーネントがHTMLタグを出力し、レスポンスを生成する。このとき、図7のHtmlSelectManyListbox101mは、データ保持部102から文字列「2005/03/04」を取得し、リストボックスを動的に生成する(ステップP35)。生成されたレスポンスは、Webブラウザ12へ送信される(ステップP36)。
このレスポンスを受信したブラウザは、上記ステップP14〜ステップP17を行うことにより、ブラウザ上の表示が更新される。すなわち、サーバ1で更新されたデータ保持部102の内容が、クライアント2のブラウザ上に反映され、クライアント2がサーバ1に同期することとなった。
以上説明したように、従来は、ユーザインタフェース上のクライアントアプリケーションにより生成されるGUI部品に、ユーザにより入力された入力値で、サーバ1のデータ保持部102で保持すべきデータを更新する(サーバ1をクライアント2に同期させる)場合、図10では、サーバ1の通信部103で上記入力値を受け取り、データ保持部103を更新し、図11では、サーバ制御部106で上記入力値を受け取ってデータベース104に一時記憶し、その後、クライアントから再びGETリクエストを受けてときに、このGETリクエストに対応するJSFの6つのフェーズの処理を実行する過程で、データベース104に記憶された入力値でデータ保持部102を更新していた。
すなわち、従来は、クライアントアプリケーション301により表示されるGUI部品に、ユーザにより入力された入力値で、サーバ1のデータ保持部102を更新する(サーバ1をクライアント2に同期させる)場合、図7〜図11に示したように、図6に示すようなJSFで規定されている6つのフェーズを含む処理手順を介さずに、当該入力値をサーバ1へ送信し、サーバ1のデータ保持部102を更新していた。
サーバ1をクライアント2に同期させるためのJSFで規定されている6つのフェーズを含む処理手順を行っていないということは、Webアプリケーション11が関知していないところで、サーバ1のデータ保持部102で記憶されているデータが更新されている、ということである。
従って、図10や図11に示す手順では、Webアプリケーション11が、サーバ1のデータ保持部102の更新を認識できずに、不具合を生ずる可能性があった。
本発明は、このような不具合をなくすために、Webアプリケーション11が、JSFで規定されている6つのフェーズを含む処理手順を行って、サーバ1をクライアント2に同期させるためのデータ保持部102の更新を行う。
このために、サーバ1のWebアプリケーション11のUIコンポーネントツリー101aは、クライアント2のクライアントアプリケーション301のコンポーネントツリー301a上の各コンポーネント(各GUI部品)に対応するUIコンポーネントを含む。
次に、本発明の実施形態について説明する。
(第1の実施形態)
図12は、サーバ1の要部を示したもので、サーバ1でWebアプリケーションプログラムを実行することにより実現される、主に、Webアプリケーション11の機能構成例を示したものである。
図13は、クライアント2の要部の構成例を示したもので、主に、クライアント2が、サーバ1から送信されたクライアントアプリケーションプログラムを実行することにより実現される機能、すなわち、クライアントアプリケーション301の機能構成例を示したものである。
図14は、サーバ1とクライアント2との間の処理手順を示したものである。
図12に示したWebアプリケーション11と、図7のWebアプリケーション11との構成上の差異は、図7の「クライアントアプリケーション起動」というUIコンポーネント101nのかわりに、図12ではクライアントアプリケーション301を構成するコンポーネントに対応するUIコンポーネント401z、401h〜401jがコンポーネントツリー301aの階層構造と同一の階層構造でUIコンポーネントツリー101aに挿入されている点である。なお、図12において、図7と同一部分は同一符号を付している。
図12のUIコンポーネント(UIJApplet)401z、UIコンポーネント(UIJLabel)401h、UIコンポーネント(UIJTextField)401i、UIコンポーネント(UIJButton)401jは、図13のコンポーネント(JApplet)301z、コンポーネント(JLabel)301h、コンポーネント(JTextField)301i、コンポーネント(JButton)301jに、それぞれ対応する。
図13のクライアントアプリケーション301と、図9のクライアントアプリケーション301との構成上の差異は、図13では、イベントハンドラ303の代わりに、イベント−HTTPリクエスト変換部304及びGETリクエスト送信命令部305が追加されている点である。なお、図13において、図9と同一部分は同一符号を付している。
コンポーネントツリー301aは、図9と同様、コンポーネント(JApplet)301zを最上位のノードとし、その子ノードとして、コンポーネント(JLable)301h、コンポーネント(JTextField)301i、コンポーネント(JButton)301jが接続された階層構造を有する。クライアントアプリケーション301が起動されると、コンポーネントツリー301a上の各コンポーネント301z、301h〜301jが、それぞれ、図15に示したように、ユーザインタフェース上の領域201z及びGUI部品201h〜201jとして表示される。
コンポーネントツリー301a上のコンポーネント301z、301h〜301jは、それぞれに対応する、ユーザインタフェース上の領域201z及びGUI部品201h〜201jの識別子はもつ。コンポーネントツリー301a上のコンポーネント301z、301h〜301jのそれぞれに対応するWebアプリケーション11上のUIコンポーネント401z、401h〜401jも、それぞれに対応するユーザインタフェース上の領域201z及びGUI部品201h〜201jの識別子はもつ。
図12のUIコンポーネント401z、401h〜401jの機能は、ほぼ他のUIコンポーネントと同様で、リクエスト・パラメータから、当該UIコンポーネントの識別子に一致するキーと値とのペアを検索し、そのようなペアがみつかったら、当該値を取得し、(4)Update Model Valuesフェーズで、バッキングビーンズ(データ保持部102)にその値を保存し、(6)Render Responseフェーズで、HTMLタグを出力するという機能である。なお、ここでは、上記リクエスト・パラメータから値を取得し、バッキングビーンズに保存するという値取得処理は、サーバ1のWebアプリケーション11のUIコンポーネント(UIJTextField)401iのみが行い、それ以外のGUI部品に対応するUIコンポーネントは、当該処理を行わない。
第1の実施形態において、図12のUIコンポーネント401z、401h〜401jが、他のUIコンポーネントと異なる点は、(6)Render Responseフェーズにおいて、上記UIコンポーネントはHTMLタグを出力しない。あるいは出力したとしてもHTMLのコメントタグなどを出力し、ブラウザが解釈可能なタグは出力しない点である。
また、UIコンポーネント(UIJApplet)401zは、図7の「クライアントアプリケーション起動」UIコンポーネント101nと同様に、アプリケーション起動命令タグを(6)Render Responseフェーズで出力する。ここでは、UIコンポーネント(UIJApplet)401zの子UIコンポーネント401h〜401jは、HTMLのコメントタグ(<!−− −−>)を(6)Render Responseフェーズで出力するものとする。
上述の機能を持つUIコンポーネントは、JSFの標準UIコンポーネントを継承し、必要に応じてメソッドをオーバーライドすることで実装することが可能である。
Sun Microsystems社がリリースしたJSF1.1のリファレンス実装では、UIコンポーネント(UIJApplet)401zは、javax.faces.component.UIPanelクラスを承継し、UIコンポーネント(UIJLabel)401hは、javax.faces.component.UIOutputクラスを承継し、UIコンポーネント(UIJTextField)401iは、javax.faces.component.UIInputクラスを承継し、UIコンポーネント(UIJButton)401jは、javax.faces.component.UICommandクラスを継承することで実装可能である。
上記JSFの標準UIコンポーネントの上位クラスにあたるjavax.faces.component.UIComponentクラスで定義されるdecodeメソッドをオーバーライドすることで、当該UIコンポーネントは、リクエスト・パラメータから当該UIコンポーネントの識別子に対応する値を取得する。本実施形態では、該メソッドをオーバーライドするのは値取得処理を行うUIコンポーネント(UIJTextFeild)401iである。UIJTextField401iは、(2) Apply Request Valuesフェーズで、当該メソッドを実行することでリクエスト・パラメータから値を抽出する。
また、同じくjavax.faces.component.UIComponentクラスで定義されるencodeBegin,encodeChildren,encodeEndの各メソッドをオーバーライドすることで、各UIコンポーネントは、所望のタグを出力する。該メソッド群は、(6)Render Responseフェーズで呼び出される。
UIコンポーネントでencodeChildrenメソッドが実行されると、当該UIコンポーネントの子コンポーネントのメソッド群を順番に呼び出す。これによって階層構造に従って再帰的にメソッド群が呼び出され、JSPタグでの階層構造に従ってHTMLタグが生成される。
本実施形態では、UIJApplet401zは、アプリケーション起動命令タグを出力し、その子コンポーネント401h〜401jは、HTMLのコメントタグを出力する。なお、各UIコンポーネントの識別子は、各コンポーネントに対応するタグクラス及びTLDファイルでプロパティ「id」により定義され、JSFアプリケーションを開発する際に、各UIコンポーネントに対応するJSPタグの当該プロパティにユニークな識別子を指定することで、各UIコンポーネントにユニークな識別子が設定される。
図13のクライアントアプリケーション301に含まれるイベント−HTTPリクエスト変換部304は、ユーザ操作によって発生したイベントを受けて、このイベントをHTTPリクエストに変換する。例えば、本実施形態の場合、コンポーネント(JButton)301jに対応するユーザインタフェース上のボタン201jの押下に伴い発生したActionEventをHTTPのリクエストに変換する。このHTTPのリクエストを通信部302を用いてWebアプリケーション11へ送信する。
ここでは、イベント−HTTPリクエスト変換部304は、リクエストヘッダーにセッションIDを示すCookieが挿入された、POSTリクエストを生成する。該セッションIDはブラウザとWebアプリケーション11とが確立したセッションのIDである。また、当該POSTリクエストのボディとして、コンポーネント(JTextField)301iに対応するGUI部品201iから取得した入力値「2005/03/04」を値、当該コンポーネント(JTextField)301iに予め定義された識別子をキーとしたリクエスト・パラメータを生成する。ここで、JTextField301i及びWebアプリケーション11のUIJTextField401iの識別子を「tf1」とすると、リクエスト・パラメータは「tf1=2005/03/04」となる。
イベント−HTTPリクエスト変換部304は、各コンポーネントから、当該コンポーネントの上記識別子を取得する。この識別子は、各コンポーネントのname属性で指定されている。
name属性はJavaのUIコンポーネントのすべての上位クラスとなるjava.awt.Componentクラスが実装している。そのためJava標準のすべてのGUI部品で、name属性を利用することが可能である。ただし、自作GUI部品で該クラスを継承しないものはname属性あるいは当該GUI部品をユニークに識別するための属性を実装する必要がある。なお、クライアントアプリケーション301の各コンポーネント301z、301h〜301jの識別子は、当該コンポーネントに対応する、Webアプリケーション11のUIコンポーネント401z、401h〜401jの識別子、すなわち、「id」プロパティの値と一致する。
本実施形態では、値として、文字列(Stringオブジェクト)を用いているが、サーバ1及びクライアント2との間で同期を取りたい値が、Stringオブジェクト以外の別のオブジェクトの場合は、直列化した上でBase64によって文字列(Stringオブジェクト)に変換し、リクエスト・パラメータとして利用できない文字「=」及び「+」をそれぞれ「_」及び空白に変換することで同期対象とすることが可能である。この場合、リクエスト・パラメータから値を抽出するUIコンポーネントが該変換に対して逆の変換をすることで元のオブジェクトを取得する。また、直列化することができないオブジェクトは、イベント−HTTPリクエスト変換部304とUIコンポーネントとの間で、予め定められた独自の文字列への変換及び逆変換ルールを実装することで値の同期が可能となる。
GETリクエスト送信命令部305は、上述のイベント−HTTPリクエスト変換部304で生成・送信されたPOSTリクエストに対するWebアプリケーション11からのレスポンスを受信した際に、ブラウザ12に対し、GETリクエストをWebアプリケーション11へ送信するように命令する機能を持つ。本実施形態のように、クライアントアプリケーション301がJavaアプレットの場合、GETリクエスト送信命令部305はApplet.showDocument(URL)を実行することなどに該当する。
次に、図14を参照しながら、サーバ1をクライアント2に同期させ、クライアント2をサーバ1へ同期させる場合の処理手順について説明する。なお、図14において、図10と同一部分には同一符号を付している。
まず、サーバ1をクライアント2に同期させる上り方向の処理動作について説明する。
クライアント2のブラウザ12から、「http://www.hello.co.jp/world.jsp」というURLへのGETリクエストが送信されてから、クライアント2で、クライアントアプリケーション301により、ブラウザ12上に、図15に示すようなユーザインタフェースを表示するまでの処理(ステップP11〜ステップP17)は、図10と同様であり、説明は省略する。
ユーザが、図15の入力テキストフィールド201iに、文字列「2005/03/04」を入力し、取得ボタン201j(コンポーネント(JButton)301j)を押下すると(ステップP18)、イベント(ActionEvent)が発生する。
ActionEventのリスナとして登録してあるイベント−HTTPリクエスト変換部304が、コンポーネント(JTextField)301iから入力値「2005/03/04」と、当該コンポーネントに予め定義された識別子「tf1」を取得し、この識別子をキーとしたリクエスト・パラメータ「tf1=2005/03/04」を生成する。そして、このリクエスト・パラメータを含む上述のPOSTリクエストを生成する(ステップP41)。クライアントアプリケーション301は、通信部302を用いて、Webアプリケーション11に、当該POSTリクエストを送信する(ステップP42)。
サーバ1のWebアプリケーション11では、当該POSTリクエストを受信すると、以下に示すような処理が行われる(ステップP43)。すなわち、図6に示した一連の処理動作が行われる。
まず、当該リクエストに含まれるCookieで指定されたセッションIDを有するWebアプリケーション11の各UIコンポーネントが、図6のステップS1の(1)Restore Viewフェーズで復元される。
図6のステップS2では、当該リクエストにリクエスト・パラメータが含まれていることから、ステップS3へ進む。
ステップS3の(2)Apply Request Valuesフェーズでは、当該リクエスト・パラメータに含まれている識別子と同一の識別子をもつUIコンポーネント(UIJTextField)401iが、当該リクエスト・パラメータから、値「2005/03/04」を取得し、ステップS4へ進み、さらにステップS5へ進む。
ステップS5の(4)Update Model Valuesフェーズでは、UIJTextField401iは、データ保持部102に、当該取得した値「2005/03/04」を記憶し、ステップS6を経由して、ステップS7へ進む。
以上の処理手順により、クライアント2のブラウザ上への新たなデータの入力に対応して、サーバ1のデータ保持部102で保持すべきデータが更新された。すなわち、サーバ1がクライアント2に同期した。
引き続き、図14を参照して、クライアント2上のWebページの表示更新するための処理、すなわち、クライアント2をサーバ1に同期させるための処理手順について説明する。
ステップS7の(6)Render Responseフェーズでは、各UIコンポーネントはHTMLタグエレメントを出力し、レスポンスを生成する。このとき、図15のリストボックス201mを生成する、図12のHtmlSelectManyListbox101mは、データ保持部102に既に登録済みの日付「2005/02/18」と、上記ステップS5で新たに登録された日付「2005/03/04」を取得して、それらを要素とするリストボックスを生成する。
ステップP44では、Webアプリケーション11で生成されたレスポンスがクライアント2へ返信される。
ところで、ステップP42では、ブラウザ12ではなく、クライアントアプリケーション301が通信部302を用いてPOSTリクエストを送信していた。従って、ステップP44で送信されるレスポンスは、クライアント2の通信部302を介して、クライアントアプリケーション301により受け取られる。従って、この時点では、ブラウザ12上の表示は更新されない。そして、レスポンスを受け取ったクライアントアプリケーション301のGETリクエスト送信命令部305は、ブラウザ12に再度GETリクエストを送信させるための命令、例えば、Applet.showDocument(http://www.hello.co.jp/world.jsp)をブラウザ12へ出力する(ステップP45)。
当該命令を受けたブラウザ12は、当該命令で指定されたURLに、GETリクエストを送信する(ステップP46)。GETリクエストを受信したWebアプリケーション11では、上記ステップP43と同様、図6に示した一連の処理動作が行われる(ステップP47)。このとき、図6のステップS2では、当該リクエストにリクエスト・パラメータが含まれていないことから、ステップS7へ進む。ステップS7の(6)Render Responseフェーズでは、各UIコンポーネントはHTMLタグエレメントを出力し、レスポンスを生成する。このとき、図15のリストボックス201mを生成する、図12のHtmlSelectManyListbox101mは、データ保持部102に既に登録済みの日付「2005/02/18」と、上記ステップS5で新たに登録された日付「2005/03/04」を取得して、それらを要素とするリストボックスを生成する。
ステップP48では、Webアプリケーション11で生成されたレスポンスがクライアント2へ返信される。なお、ステップP46では、ブラウザ12がGETリクエストを送信していたので、ステップP48で送信されるレスポンスは、クライアント2のブラウザ12により受け取られる。
この時点で、ブラウザ12は、更新された日付を持つリストボックスを含むWebページを表示し、画面が更新される。その結果、クライアント2がサーバ1に同期した。
なお、ステップP43で送信されたレスポンスには、クライアントアプリケーション起動命令タグが含まれているため、ブラウザ12は、再度、クライアントアプリケーション記憶部105に対してGETリクエストを送信し(ステップP50)、クライアントアプリケーションのアーカイブを取得し(ステップP51)、クライアントアプリケーションを再起動する(ステップP52)。この時点でブラウザ12による表示は、完全に更新され、図16に示す表示状態になる。
なお、第1の実施形態では、POSTリクエスト中のリクエスト・パラメータの書式として、「tf1=2005/03/04」としているが、この場合に限らず、変換ルールを定めることで、「tf1=n,“2005/03/04の変換後の文字列“」とすることも可能である。これによって、入力フィールド201iに入力される値が文字列ではない場合でも対応可能となる。例えば、入力フィールド201iにリストやテーブルを用いることも可能となる。前者の場合Stringの一次元配列を、後者の場合Stringの二次元配列を変換すればよい。ただし、以後の実施形態では、説明の簡単のためにリクエストパラメータとして「tf1=2005/03/04」という書式を用いるものとする。
また、第1の本実施形態では、クライアントアプリケーションにより表示される各GUI部品に対応するWebアプリケーション11のUIコンポーネント群が、GUI部品群の階層構造と同じ階層構造をもつ場合を示しているが、この第1の実施形態及び他の実施形態は、この場合に限らない。UIコンポーネント群が、GUI部品群の階層構造とは異なる階層構造を持っている場合も、階層構造をもたない場合も、第1の実施形態及び他の実施形態に適用可能である。
しかし、UIコンポーネント群がGUI部品群と同じ階層構造をもつことで、Webアプリケーションとクライアントアプリケーションの開発時に、開発者に両者の構造を分かり易くするという効果がある。また、両者の階層構造を一致させることで、一方のアプリケーションを入力として他方のアプリケーションのテンプレートを機械的に生成するツールなどの開発が容易になる。ここでツールは、例えばアプレットプログラムが入力されると、アプレットプログラムを構成する各GUI部品に対応するJSPタグが同一の階層構造で配置されたJSPページのテンプレートを生成する。もしくは、GUI部品に対応するJSPタグを階層的に配置したJSPページを入力として、同一の階層構造をもつGUI部品から構成されるアプレットプログラムのテンプレートを生成する。このように、望ましくは、Webアプリケーションとクライアントアプリケーションとは同一の階層構造をもつことが望ましい。
(第2の実施形態)
図17は、サーバ1の要部を示したもので、サーバ1でWebアプリケーションプログラムを実行することにより実現される、主に、Webアプリケーション11の機能構成例を示したものである。
図18は、クライアント2の要部の構成例を示したもので、主に、クライアント2が、取得したクライアントアプリケーションプログラムを起動することにより実現される機能、すなわち、クライアントアプリケーション301の機能構成例を示したものである。
図19は、サーバ1とクライアント2との間の処理手順を示したものである。
図20は、ユーザにより値が入力される前のユーザインタフェースの表示例を示し、図21は、ユーザにより値が入力された後、サーバ1とクライアント2とが相互に同期したときの画面表示例である。なお、図19及び図20において、図15、図16と同一部分には同一符号を付している。
図17に示したWebアプリケーション11と、図12に示したWebアプリケーション11との差異は、図12では、取得済みの休暇の日付を表示するためのGUI部品201l、201mを、Webアプリケーションから送信されるレスポンスを用いてブラウザに表示するために、UIコンポーネント(HtmlOutputLabel)101lとUIコンポーネント(HtmlSelectManyListbox)101mを用いているが、これらの代わりに、図17では、GUI部品201l、201mをクライアント2のクライアントアプリケーション301で表示するために、UIコンポーネント(UIJApplet)401zの子のUIコンポーネントの、UIコンポーネント(UIJLabel)501lと、UIコンポーネント(UIJList)501mが挿入されている点である。なお、図17において、図12と同一部分には同一符号を付している。
図17のWebアプリケーション11のUIコンポーネントツリー101aのUIコンポーネント(UIJApplet)401zの子のUIコンポーネント401h〜401j、501l、501mは、いずれも(6)Render Responseフェーズで、HTMLのコメントタグ(<!−− −−>)などのWebブラウザが解釈しないタグエレメントを出力し、これらタグには、クライアント1側と同期を取りたいGUI部品(コンポーネント)の識別子と値とが挿入されている。すなわち、コメントタグであれば、例えば、<!−− lst1=2005/02/18 −−>を出力する。なお、第2の実施形態では、コメントタグを用いる場合を例にとり説明するが、この場合に限らず、ブラウザ12が解釈しないタグであればどのようなタグを用いても良い。
UIコンポーネント(UIJApplet)401zは、第1の実施形態と同様、(6)Render Responseフェーズで、クライアントアプリケーション起動命令タグを出力する。
図18のクライアントアプリケーション301と、図13のクライアントアプリケーション301との差異は、図18のクライアントアプリケーション301には、取得済みの休暇の日付を表示するためのGUI部品201l、201mに対応するコンポーネント(JLabel)601lとコンポーネント(JList)601mが、コンポーネントツリー301aに新たに追加されている点である。また、図18のクライアントアプリケーション301は、図13のGETリクエスト送信命令部305の代わりに、レスポンス適用部306が追加されている。レスポンス適用部306は、Webアプリケーション11からのレスポンスから、上述のコメントタグ内に記述されている値を取得し、GUI部品に適用する機能を持つ。なお、図18において、図13と同一部分には同一符号を付している。
なお、ここで、上記第1の実施形態と同様、図17のUIコンポーネント(UIJLabel)501lとUIコンポーネント(UIJList)501mは、図18のコンポーネント(JLabel)601lとコンポーネント(JList)601mにそれぞれ対応する。そして、図17のUIコンポーネント(UIJLabel)501lと、図18のコンポーネント(JLabel)601l(図20及び図21のGUI部品201l)とは同じ識別子をもち、図17のUIコンポーネント(UIJList)501mは、図18のコンポーネント(JList)601m(図20及び図21のGUI部品201m)と同じ識別子をもつ。
このような構成において、図18のイベント−HTTPリクエスト変換部304が送信したPOSTリクエストを、図17のWebアプリケーション11が受けたとき、UIコンポーネント(UIJList)501mは、図6の(6)Render Responseフェーズの処理で、リストボックスに表示すべき値をデータ保持部102から取得し、取得した値と当該UIコンポーネント(UIJList)501mの識別子がコメントとして挿入されたコメントタグ(<!−−UIJList501mの識別子=取得した値−−>)を出力する。このようなコメントタグ(コメントエレメント)を含むHTMLテキストが、当該POSTリクエストに対するレスポンスとして、クライアント2へ返送される。
このレスポンスは、図18の通信部302で受信され、レスポンス適用部306へ渡される。レスポンス適用部306は、当該レスポンスに含まれる上記コメントタグから上記識別子と値を取得し、当該識別子に対応するコンポーネント(UIJList)601m、すなわち、リストボックス201mに当該値をセットする。
次に、図19を参照しながら、サーバ1をクライアント2に同期させる場合の処理手順及び、クライント2をサーバ1に同期させる場合の処理手順について説明する。なお、図19において、図10、図14と同一部分には同一符号を付している。
図19のステップP11〜ステップP18、ステップP41〜ステップP43までのサーバ1をクライアント2に同期させるまでの処理は、図10、図14と同一である。すなわち、ステップP11〜ステップP17までの処理により、ブラウザ12上に、図20に示すようなユーザインタフェースが表示される。なお、ここでは、過去に、入力テキストフィールド201iに、「2005/02/18」が入力して、この値をリストボックス201mに表示するための(クライアント2とサーバ1とが互いに同期するための)、図19に示す処理手順を既に実行した後の状態を示している。なお、ステップP11〜ステップP17までの処理により、図20に示すようなユーザインタフェースを表示するための手法は、第3の実施形態で説明する。
ユーザが、図20の入力テキストフィールド201iに、文字列「2005/03/04」を新たに入力し、取得ボタン201jを押下すると、イベント(ActionEvent)が発生する。すると、イベント−HTTPリクエスト変換部304が、入力テキストフィールド201iから入力値「2005/03/04」と、当該GUI部品に予め定義された識別子「tf1」を取得し、この識別子をキーとしたリクエスト・パラメータ「tf1=2005/03/04」を生成する。そして、このリクエスト・パラメータを含むPOSTリクエストを生成し、通信部302からサーバ1へ送信する(ステップP18、ステップP41、ステップP42)。
サーバ1では、当該POSTリクエストを受信すると、図6に示した一連の処理動作を行い、当該リクエスト中のリクエスト・パラメータに含まれている識別子と同一の識別子をもつUIコンポーネント(UIJTextField)401iが、当該リクエスト・パラメータから、値「2005/03/04」を取得し、この値をデータ保持部102に記憶する(ステップP43)。
以上の処理手順により、クライアント2のブラウザ上への新たなデータの入力に対応して、サーバ1のデータ保持部102で保持すべきデータが更新された。すなわち、サーバ1がクライアント2に同期した。
次に、クライント2をサーバ1に同期させる場合の処理手順について説明する。
ステップS43において、UIコンポーネント(UIJTextField)401iが、当該リクエスト・パラメータに含まれていた値「2005/03/04」をデータ保持部102に記憶すると、次に、UIコンポーネント(UIJList)501mは、図6の(6)Render Responseフェーズで、データ保持部102から、リストボックスに表示すべき値を全て取得し、取得した値と当該UIコンポーネント(UIJList)501mの識別子がコメントとして挿入されたコメントエレメント、例えば、<!−−lst1=2005/02/18,2005/03/04−−>を生成する。このようなコメントエレメントを含むレスポンスが、クライアント2のクライアントアプリケーション301へ返信される(ステップP61)。
上記レスポンスをクライアント2の通信302を介して受信したクライアントアプリケーション301は、そのレスポンスを、レスポンス適用部306に渡す(ステップP62)。当該レスポンスを受け取ったレスポンス適用部306は、当該レスポンス中のコメントタグに、クライアントアプリケーション301中のUIコンポーネントのいずれかの識別子が含まれているときには、当該コメントタグから、当該識別子(ここでは、UIJList501mの識別子「lst1」)とともに書き込まれている値(ここでは、「2005/02/18」、「2005/03/04」)を取り出す(ステップP63)。そして、この取り出された値を、当該識別子「lst1」に対応するGUI部品であるリストボックス201mにセットする(表示させる)。すなわち、「2005/02/18」及び「2005/03/04」が、リストボックス201mに表示される(ステップP64)。このときのブラウザ上の表示例を図21に示す。
以上の処理手順により、サーバ1で更新されたデータ保持部102の内容が、クライアント2のブラウザ上に反映され、クライアント2がサーバ1に同期することとなった。
(第3の実施形態)
第3の実施形態では、上記第2の実施形態のように、クライアントアプリケーション301が、データ保持部102に記憶された値を表示するGUI部品、例えば、上記第2の実施形態ではリストボックス201m(コンポーネント(JList)601m)を含む場合に、クライアントアプリケーション起動時に、当該GUI部品に、Webアプリケーション11からParamタグを用いて通知された、データ保持部102が持つ初期値を表示させる機能(Paramタグ適用部307)について説明する。
ここでは、第2の実施形態に、この機能(Paramタグ適用部307)を適用した場合を例にとり説明する。
サーバ1の構成は、第2の実施形態の図17と同様である。また、Webアプリケーション11では、クライアント2からリクエストを受けたときに、(6)Render Responseフェーズにおいて、UIコンポーネント(UIJList)501mは、データ保持部102が保持する初期値を取得すると、当該初期値と、UIコンポーネント(UIJList)501mの識別子を含む、JSPの(UIコンポーネント(UIJApplet)401zが出力するクライアントアプリケーション起動命令タグの)パラメータタグエレメント(Paramタグ)を生成する点が、第2の実施形態と異なる。
クライアント2の構成例を図22に示す。なお、図18と同一部分には同一符号を付している。図22において図18と異なる点は、図22のクライアントアプリケーション301では、新たなに、Paramタグ適用部307が追加されている。
Paramタグ適用部307は、Webアプリケーション11からのレスポンスに含まれるParamタグに含まれている値を抽出し、当該Paramタグに含まれている識別子で特定されるUIコンポーネントに、当該抽出された値を適用する機能を有する。
次に、図23を参照して、図19のステップP11〜ステップP17の処理により、Webアプリケーション11が保持する初期値を、クライアントアプリケーションに表示させるための処理手順を説明する。なお、ここでは、第3の実施形態に係る要部について説明し、それ以外は、図19と同様である。
ステップP11で、ブラウザ12から送信されたGETリクエストを、Webアプリケーション11が受信すると、ステップP12において、Webアプリケーション11のUIJList501mは、(6)Render Responseフェーズの処理で、データ保持部102から値を取得し、UIApplet401zが出力するクライアントアプリケーション起動命令のParamタグ<applet ….><Param name=lst1 value=2005/02/18></applet>を生成する。
このParamaタグをもつクライアントアプリケーション起動命令を含むレスポンスが、ブラウザ12に返信される(ステップP13)。
このレスポンスを受信したブラウザ12は、このHTMLテキストを解釈してユーザインターフェースを描画するとともに(ステップP14)、クライアントアプリケーションの保存場所に対してGETリクエストを送信する(ステップP15)。
クライアントアプリケーション記憶部105は、このGETリクエストを受けて、クライアントアプリケーションのアーカイブを読み出し、これをボディとするレスポンスを返信する(ステップP16)。
レスポンスを受信したブラウザ12により、クライアントアプリケーション301が起動される(ステップP17a)。
ブラウザ12により起動されたクライアントアプリケーション301は、起動後に、Paramタグで指定された値を取得する。例えば、Paramタグ適用部307は、クライアントアプリケーションがアプレットの場合、Applet.getParameter()を用いて、Paramタグ内の識別子と値を取得する。ブラウザ12がクライアントアプリケーションプログラムを取得し、起動すると、Paramタグ適用部307は、上記処理により識別子(lst1)で識別されるJList601mに値を出力し(ステップP17b)、描画を更新する。更新した結果、ブラウザ12の表示状態は図20に示したようになる。
第3の実施形態では、クライアントアプリケーション起動時の初期値の表示方法について説明している、勿論クライアントアプリケーションの再起動時にクライアントアプリケーションの表示を更新する場合にも適用可能である。
(第4の実施形態)
次に、第4の実施形態として、第3の実施形態で用いたParamタグと、第2の実施形態で用いたコメントタグとを用いて、クライアント2とサーバ1との間で相互に同期させるための手法について説明する。
サーバ1の構成は、第2の実施形態の図17と同様である。また、Webアプリケーション11では、クライアント2からPOSTリクエストを受けたときに、(6)Render Responseフェーズにおいて、UIコンポーネント(UIJList)501mは、データ保持部102が保持する値を取得すると、当該値と、UIコンポーネント(UIJList)501mの識別子を含む、コメントタグを生成する。さらに、Webアプリケーション11では、クライアント2からGETリクエストを受けたときに、(6)Render Responseフェーズにおいて、UIコンポーネント(UIJList)501mは、データ保持部102が保持する値を取得すると、当該値と、UIコンポーネント(UIJList)501mの識別子を含む、UIコンポーネント(UIJApplet)401zが出力するクライアントアプリケーション起動タグのParamタグを生成する。
クライアント2の構成例は図22と同様である。
図24は、サーバ1をクライアント2に同期させる場合の処理手順及び、クライント2をサーバ1に同期させる場合の処理手順について説明する。なお、図24において、ステップP11からステップP17までの処理は、第3の実施形態の図23と同様である。また、図24のステップP18以降は、第2の実施形態の図19と同様である。すなわち、第3の実施形態で説明したように、ステップP11からステップP17までの処理により、図20に示すような画面がブラウザ12により表示される。
その後、ユーザが、図20の入力テキストフィールド201iに、文字列「2005/03/04」を新たに入力し、取得ボタン201jを押下すると、イベント(ActionEvent)が発生する。そして、イベント−HTTPリクエスト変換部304が、コンポーネント(JTextField)301iから入力値「2005/03/04」と、当該コンポーネントに予め定義された識別子「tf1」を取得し、この識別子をキーとしたリクエスト・パラメータ「tf1=2005/03/04」を生成する。そして、このリクエスト・パラメータを含むPOSTリクエストを生成し、通信部302からサーバ1へ送信する(ステップP18、ステップP41、ステップP42)。以降の処理は、第2の実施形態の図19と同様であり、ステップP64では、図21に示すように、表示内容が更新される。
(第5の実施形態)
第5の実施形態では、ユーザインタフェースに、クライアントアプリケーション301により表示されるテキストフィールドと、Webアプリケーション11から送信されたHTMLのタグエレメントにより表示されるテキストフィールドとが存在する場合に、この2つのテキストフィールドのそれぞれに入力された2つの入力値で、サーバ1のデータ保持部102を更新し、更新後のデータ保持部102内の値で、ユーザインタフェースの表示を更新するための手法について説明する。
図25は、第5の実施形態に係るサーバ1の有する機能の構成例を示したもので、主に、サーバ1でWebアプリケーションプログラムを実行することにより実現される機能(Webアプリケーション11)の構成例を示している。なお、図25において、図12と同一部分には同一符号を付している。
図26は、第5の実施形態に係るクライアント2の有する機能の構成例を示したもので、主に、クライアント2でクライアントアプリケーションプログラムを起動することにより実現される機能(クライアントアプリケーション301)の構成例を示している。なお、図26において、図13と同一部分には同一符号を付している。
図28は、クライアント2のブラウザにより最初に表示される画面表示例を示している。また、図29は、図28の入力テキストフィールド201q、201iに、削除する「取得済み」の日付、新たな日付をそれぞれ入力した後に、サーバ1とクライアント2との間で相互に同期がとれたときの画面表示例を示している。
図28及び図29において、文字列「削除日付」、テキストフィールドなどのGUI部品201p、201qが新たに追加されている。これらGUI部品は、Webアプリケーション11のUIコンポーネント(HtmlOutputLabel)601pと、UIコンポーネント(HtmlInputText)601qによりそれぞれ生成されたものである。
文字列「登録日時」、テキストフィールド、「実行」ボタンといったGUI部品201h〜201jが、クライアントアプリケーション301により表示される。
図25のWebアプリケーション11は、第1の実施形態と同様、ユーザインタフェース上の休暇の「取得済み」日付を表示するためのリストボックス201mを、UIコンポーネント(HtmlSelectManyListbox)101mにより生成している。また、「取得済み」の日付を削除するための入力テキストフィールド201qを、UIコンポーネント(HtmlInputText)601qにより生成している。
図25でのWebアプリケーション11では、フィルター部701が追加されている点で、第1の実施形態と大きく異なるが、Webアプリケーション11のUIコンポーネント401z、401h〜401jは、第1の実施形態と同様、ブラウザ12が解釈可能なHTMLタグは出力しない。
なお、ここでは、Webアプリケーション11のうち、UIコンポーネントツリー101aにより、図6に示す処理を行う部分をWebアプリケーション11の本体と呼ぶ。
Webアプリケーション11のフィルター部701は、リクエスト受信部701a、リクエストパラメータ抽出部701b、リクエスト応答部701c、リクエストパラメータマージ部701d、リクエスト種別判定部701e、リクエスト転送部701fから構成される。
ここで、図30に示すフローチャートを参照して、フィルター部701の処理動作について説明する。
フィルター部701のリクエスト受信部701aは、クライアント2からのリクエストをWebアプリケーション11の本体が受信する前に、当該リクエストをインターセプトする。
リクエスト受信部701aが、クライアント2からのリクエストを受信する(ステップT1)と、まず、リクエスト種別判定部701eが、受信したHTTPリクエストの種別を判定する。まず、リクエストのメソッドを調べる(ステップT2)。メソッドがGETであればそのままWebアプリケーション11の本体に転送する(ステップT11)。メソッドがPOSTであれば、リクエスト・パラメータに予め定められたフラグパラメータ(例えばapplet=appletなど)が入っているか否かを調べる(ステップT3)。当該フラグパラメータが含まれている場合、当該リクエストは、「1番目のリクエスト」であると判定する。
次に、リクエストパラメタータ抽出部701bは、この1番目のリクエストから、フラグパラメータ以外のパラメータを抽出する(ステップT4)。そして、1番目のリクエストに含まれているセッションIDとともに、抽出されたパラメータを、リクエスト・パラメータ一時記憶部702に記憶する(ステップT5)。このとき、セッションIDを検索時のキーとなるように、抽出されたパラメータを、リクエスト・パラメータ一時記憶部702に記憶する。そして、リクエスト応答部701cが、1番目のフィルター処理が成功した旨のレスポンス(200 OKなど)をクライアント2へ返信する(ステップT6)。
その後、再び、クライアント2からのリクエストを受信すると、上記同様に処理を行う。このとき、ステップT3において、受信したPOSTリクエスト中にフラグパラメータが入っていない場合、ステップT7へ進み、当該POSTリクエスト中のセッションIDが、1番目のリクエストと判定されているリクエストのものと同一かどうかを判定する(ステップT7)。セッションIDが同一であれば、リクエスト種別判定部701eは、当該受信したPOSTリクエストは「2番目のリクエスト」であると判定する。
2番目のリクエストが得られると、次に、リクエストパラメータマージ部701dが、リクエストパラメータ一時記憶部702から、前回のステップT5で記憶した、1番目のリクエスト中のリクエスト・パラメータを取得する。そして、1番目と2番目のリクエスト中のリクエスト・パラメータをマージし、リクエストパラメータ一時記憶部702から、取得した1番目のリクエストのリクエスト・パラメータを削除する(ステップT8)。
その後、リクエスト転送部701fは、マージされたリクエスト・パラメータを含むPOSTリクエストを、Webアプリケーションの本体に転送する(ステップT9)。
なお、ステップT7で、今回受信したリクエスト中のセッションIDが、1番目のリクエストのセッションIDと異なる場合には、リクエスト応答部701cが、フィルター処理が失敗した旨のレスポンス(500 Internal Server Errorなど)をクライアントに返信する(ステップT10)。
なお、フィルター部701は、JSFの場合、サーブレットフィルターを図30に示した処理を行うように実装することで実現可能である。また、リクエストパラメータ一時記憶部702は、JSFの場合、HttpSessionオブジェクトに対応する。
図26のクライアントアプリケーション301は、イベント−HTTPリクエスト変換部304、サブミット命令部308及びエラー処理部309が含む。
サブミット命令部1314は、イベント−HTTPリクエスト変換部304が、通信部302を介して送信したPOSTリクエストに対する1番目のフィルター処理が成功した旨のレスポンス(200 OKなど)を受信した際に、ブラウザ12に、POSTリクエストを送信するように(サブミットするように)命令する。
クライアントアプリケーションがアプレットの場合、Javaメソッドを呼び出すことでJavaScriptを実行し、ブラウザ12にサブミットさせることが可能である。
エラー処理部309は、イベント−HTTPリクエスト変換部304が、通信部302を介して送信したPOSTリクエストに対するフィルター処理失敗のレスポンス(500 Internal Server Errorなど)を受信した際に、処理を終了してエラーが発生したことをユーザに通知する。通知するためにはポップアップでメッセージを出力しても良いし、クライアントアプリケーション301上にエラーメッセージを表示しても良い。
図27は、サーバ1とクライアント2との間の処理手順を示したものである。なお、図27において、図14と同一部分には同一符号付している。
ユーザが、ブラウザ12に、例えば、「http://www.hello.co.jp/world.jsp」というURLを入力し、該URLに対するGETリクエストを送信すると(ステップP101)、フィルター部701が受信する(ステップP102)。
フィルター部701では、図30に示すような処理動作を行う。すなわち、リクエスト受信部701aが、当該GETリクエストを受信すると(ステップT1)、リクエスト種別判定部701eは、当該リクエストのメソッドがGETであるため、ステップT11へ進み、当該リクエストをWebアプリケーション11の本体に転送する(ステップP103)。
その後、クライアントアプリケーション301を起動するまでのステップP12からステップP17までの処理は、図10と同様であり、説明は省略する。
ステップP17までの処理により、ブラウザ12に、図28に示すようなユーザインターフェースが表示されたとする。図28では、取得済みの休暇の日付として、リストボックス201mに「2005/02/18」が表示されている。
さて、ユーザが、図34の入力テキストフィールド201iに追加したい日付文字列「2005/03/04」を入力し、入力テキストフィールド201qに削除したい日付文字列「2005/02/18」を入力した後、実行ボタン201jを押下するとActionEevntが発生する(ステップP18)。
このとき、当該ActionEventをフックした、イベント−HTTPリクエスト変換部304は、予め定められたフラグパラメータ(例えば、applet=applet)と、入力テキストフィールド201iの識別子及び値「tf1=2005/03/04」とを&で繋いだ「applet=applet&tf1=2005/03/04」をリクエスト・パラメータとして含む、POSTリクエストを生成する(ステップP101)。そして、このPOSTリクエストを通信部302を介してWebアプリケーション11へ送信する(ステップP102)。
当該リクエストは、まず、Webアプリケーション11のフィルター部701により受信される。フィルター部701では、図30に示すような処理動作を行う(ステップP103)。すなわち、リクエスト受信部701aが、当該POSTリクエストを受信すると(ステップT1)、リクエスト種別判定部701eは、当該POSTリクエストのリクエスト・パラメータにフラグパラメータ(applet=applet)が入っていることから、「1番目のリクエスト」であると判定する(ステップT2〜ステップT3)。そして、リクエストパラメタータ抽出部701bは、この1番目のリクエストから、フラグパラメータ以外のパラメータを抽出する(ステップT4)。そして、1番目のリクエストに含まれているセッションIDとともに、抽出されたパラメータを、リクエスト・パラメータ一時記憶部702に記憶する(ステップT5)。リクエスト応答部701cが、1番目のフィルター処理が成功した旨のレスポンスをクライアント2へ返信する(ステップT6)。
このようにしてWebアプリケーション11からレスポンスが送信されると(ステップp04)、当該レスポンスは、クライント2のクラインとアプリケーション301は、通信部302介して受信される。
このレスポンスを受けて(ステップP105)、サブミット命令部308が、ブラウザ12に対し、POSTリクエストを送信するように(サブミットするように)命令する(ステップP106)。
この命令を受けて、ブラウザ12は、入力テキストフィールド201qの識別子「tf2」と、当該入力テキストフィールド201qに入力された値「2005/02/18」とからなるリクエスト・パラメータ「tf2=2005/02/18」を、そのボディに含むPOSTリクエストを送信する(ステップP107)。
当該リクエストは、Webアプリケーション11のフィルター部701により受信される。フィルター部701では、図30に示すような処理動作を行う(ステップP108)。すなわち、リクエスト受信部701aが、当該POSTリクエストを受信すると(ステップT1)、リクエスト種別判定部701eは、当該POSTリクエストのリクエスト・パラメータにフラグパラメータ(applet=applet)が存在せず(ステップT2〜ステップT3)、しかも、当該リクエスト中のセッションIDが、「1番目のリクエスト」のセッションIDと同一であることから、当該受信したPOSTリクエストは「2番目のリクエスト」であると判定する(ステップT7)。
2番目のリクエストが得られると、次に、リクエストパラメータマージ部701dが、リクエストパラメータ一時記憶部702から、1番目のリクエスト中のリクエスト・パラメータを取得する。そして、1番目と2番目のリクエスト中のリクエスト・パラメータをマージし(結合し)、リクエストパラメータ一時記憶部702から、取得した1番目のリクエストのリクエスト・パラメータを削除する(ステップT8)。その後、リクエスト転送部701fは、マージされたリクエスト・パラメータを含むPOSTリクエストを、Webアプリケーション11本体に転送する(ステップT9)。
このようにして、2つのリクエストパラメータがマージされたPOSTリクエストが、Webアプリケーション11の本体に転送されると(ステップP109)、当該リクエストを受信したWebアプリケーション11は、図6の処理を行う(ステップP110)。
すなわち、(2)Apply Request Valuesフェーズで、図25のUIJTextField401iが
マージされたリクエスト・パラメータ中の値「2005/03/04」を取得し、図25のHtmlInputText601qが、マージされたパラメータ中の値「2005/02/18」を取得する。そして、(4)Update Model Valuesフェーズでは、データ保持部102に「2005/03/04」が記憶され、「2005/02/18」が削除される。
以上の処理により、サーバ1がクライント2に同期した。
次に、(6)Render Responseフェーズでは、各UIコンポーネントはHTMLタグエレメントを出力し、レスポンスを生成する。このとき、更新後のデータ保持部102からは、「2005/02/18」は存在しないため、図28のリストボックス201mを生成する、図25のHtmlSelectManyListbox101mは、更新後のデータ保持部102に記憶されている「2005/03/04」を取得して、それらを要素とするリストボックスを生成する。
ステップP111では、Webアプリケーション11で生成されたレスポンスがクライアント2へ返信される。
当該レスポンスはブラウザ12で受信され、ブラウザ12は、当該レスポンスを用いて、ユーザインタフェースを描画することで、表示が更新する(ステップP112)。すなわち、ユーザインタフェース上のリストボックス201mの表示が更新され、リストボックス201mには「2005/03/04」が表示される。
さらに、ブラウザ12は、当該レスポンスに含まれるクライアントアプリケーション起動命令により、GETリクエストをクライアントアプリケーション記憶部105に送信し(ステップP113)、クライアントアプリケーションプログラムを取得する(ステップP114)。
そして、ブラウザ12は、クライアントアプリケーション301を再起動して、ユーザインタフェース上のGUI部品201h〜201jが表示される(ステップP115)このときの画面表示例を図29に示す。
以上の処理により、サーバ1とクライアント2とが相互に同期した。
(第6の実施形態)
上記第5の実施形態では、ユーザインタフェースに、クライアントアプリケーション301により表示される入力フィールド201iと、Webアプリケーション11により生成されるHTMLのタグエレメントにより表示される入力フィールド201qとが存在する場合に、この2つの入力フィールドのそれぞれに入力された2つの入力値で、サーバ1のデータ保持部102を更新し、更新後のデータ保持部102内の値で、ブラウザ12上のユーザインタフェースの表示を更新するための手法を示した。
上記第5の実施形態では、特に、ユーザインターフェースのリストボックス201mは、Webアプリケーション12により生成されるHTMLのタグエレメントにより表示される場合の手法を示した。
次に、第6の実施形態では、ユーザインターフェースのリストボックス201mは、クライントアプリケーション301により表示される場合について説明する。
図31は、第6の実施形態に係るサーバ1の有する機能の構成例を示したもので、主に、サーバ1でWebアプリケーションプログラムを実行することにより実現される機能(Webアプリケーション11)の構成例を示している。なお、図31において、図17、図25と同一部分には同一符号を付している。
図32は、第5の実施形態に係るクライアント2の有する機能の構成例を示したもので、主に、クライアント2でクライアントアプリケーションプログラムを起動することにより実現される機能(クライアントアプリケーション301)の構成例を示している。なお、図32において、図18、図26と同一部分には同一符号を付している。
図34は、クライアント2のブラウザにより最初に表示される画面表示例を示している。また、図35は、図34の入力テキストフィールド201q、201iに、削除する「取得済み」の日付、新たな日付をそれぞれ入力した後に、サーバ1とクライアント2との間で相互に同期がとれたときの画面表示例を示している。
図34及び図35において、文字列「削除日付」、テキストフィールドなどのGUI部品201p、201qは、Webアプリケーション11のUIコンポーネント(HtmlOutputLabel)601pと、UIコンポーネント(HtmlInputText)601qによりそれぞれ生成されたものである。
文字列「登録日時」、テキストフィールド、「実行」ボタン、文字列「取得済み」、リストボックス、といったGUI部品201h〜201j、201l、201mは、クライアントアプリケーション301のコンポーネント301h〜301j、601l、601mにそれぞれ対応する。
図31のWebアプリケーション11は、図25のWebアプリケーションのUIコンポーネント(HtmlPanelGrid)101k、UIコンポーネント(HtmlOutputLabel)101lとUIコンポーネント(HtmlSelectManyListbox)101mの代わりに、クライアントアプリケーション301のコンポーネント601l、601mに対応する、UIコンポーネント(UIJLabel)501lとUIコンポーネント(UIJList)501mを備えている。
このような構成により、図31のWebアプリケーション11は、前述の第3の実施形態と同様、Paramタグを用いて、クライアントアプリケーション301に、ユーザインタフェース上のGUI部品に表示すべき値を通知する。このために、Webアプリケーション11がGET/POSTリクエストを受信した際の(6)Render Responseフェーズにおいて、UIコンポーネント(UIJList)501mが、データ保持部102が保持する値を取得し、当該値と、UIコンポーネント(UIJList)501mの識別子を含む、Paramタグを生成する。このParamタグは、第3の実施形態と同様、UIコンポーネント(UIJApplet)401zが出力するクライアントアプリケーション起動タグに含まれている。
クライアントアプリケーション起動タグのParamタグは、例えば、次のような形式のものである。
<applet ...><Param name=lst1 value=2005/02/18></applet>
ここで、「lst1」は、UIコンポーネント(UIJList)501m及びクライアントアプリケーション301のコンポーネント(JList)601mの識別子である。また、値「2005/02/18」は、(6)Render Responseフェーズで、データ保持部102に保存されていた値である。
図32のクライアントアプリケーション301と、図26のクラインとアプリケーション301とで異なる点は、図32のクライアントアプリケーション301では、図26のクライントアプリケーション301のコンポーネントツリー301aに、文字列「取得済み」、リストボックス、といったGUI部品201l、201mに対応するコンポーネント(JLabel)601lと、コンポーネント(JList)601mが追加されている。また、図32のクライアントアプリケーション301には、第3の実施形態で説明した、Paramタグ適用部307が追加されている。
Paramタグ適用部307は、クライアントアプリケーション起動時に、コンポーネント(JList)601mに対応するリストボックス201mに、Webアプリケーション11からParamタグを用いて通知された、データ保持部102が持つ値を表示させる。
図33は、サーバ1とクライアント2との間の処理手順を示したものである。なお、図33において、図27と同一部分には同一符号付している。
図33の、ステップP101で、ユーザが、ブラウザ12に、例えば、「http://www.hello.co.jp/world.jsp」というURLを入力し、該URLに対するGETリクエストを送信してから、ステップP17で、クライアントアプリケーション301を起動するまでの処理は、図27と同様であり、異なる点についてのみ説明する。すなわち、ステップP12で、GETリクエストを受信したWebアプリケーション11のUIコンポーネント(UIJList)501mは、(6)Render Responseフェーズにおいて、データ保持部102に既に記憶されていた値「2005/02/18」を上述のようにParamタグに挿入する。このParamタグを有するクライアントアプリケーション起動タグを含むレスポンスが、ブラウザ12へ返信される(ステップP13)。
さて、ステップP17で、クライアントアプリケーション301が起動されると(ステップP17a)、Paramタグ適用部307は、ステップP13でWebアプリケーション11から送信されたレスポンス中のParamタグから、識別子と値を抽出し、当該識別子に対応するUIコンポーネント(JList)601m、すなわち、リストボックス201mに、当該抽出された値を出力する(ステップP17b)。その結果、図34に示すように、リストボックス201mには、値「2005/02/18」が表示される。
続いて、第5の実施形態と同様、ユーザが、図34の入力テキストフィールド201iに追加したい日付文字列「2005/03/04」を入力し、入力テキストフィールド201qに削除したい日付文字列「2005/02/18」を入力した後、実行ボタン201jを押下するとActionEevntが発生する(ステップP18)。
その後のステップP101〜ステップP109までの処理は、第5の実施形態と同様であり、説明は省略する。
ステップP109で転送された、2つのリクエストパラメータがマージされたPOSTリクエストを受信すると、ステップP110において、Webアプリケーション11は、図6の処理を行う。
すなわち、(2)Apply Request Valuesフェーズで、図25のUIJTextField401iがマージされたリクエスト・パラメータ中の値「2005/03/04」を取得し、図25のHtmlInputText601qが、マージされたパラメータ中の値「2005/02/18」を取得する。そして、(4)Update Model Valuesフェーズでは、データ保持部102に「2005/03/04」が記憶され、「2005/02/18」が削除されて、サーバ1がクライント2に同期した。
ここまでの処理は、第5の実施形態と同様である。第5の実施形態と異なるのは、(6)Render Responseフェーズの処理である。
第6の実施形態では、(6)Render Responseフェーズにおいて、UIJList501mは、更新後のデータ保持部102に既に記憶されていた値「2005/03/04」を上述のようにParamタグに挿入する。このParamタグを有するクライアントアプリケーション起動タグを含むレスポンスが、ブラウザ12へ返信される(ステップP111)。
当該レスポンスはブラウザ12で受信され、さらに、ブラウザ12は、当該レスポンスに含まれるクライアントアプリケーション起動命令により、クライアントアプリケーション記憶部105から、クライアントアプリケーションプログラムを取得する(ステップP113〜ステップP114)。
そして、ブラウザ12は、上記ステップP17と同様、クライアントアプリケーション301を再起動する(P115a)。すると、Paramタグ適用部307は、ステップP114でWebアプリケーション11から送信されたレスポンス中のParamタグから、識別子と値を抽出し、当該識別子に対応するUIコンポーネント(JList)601m、すなわち、リストボックス201mに、当該抽出された値を出力する(ステップP115b)。その結果、図35に示すように、リストボックス201mには、値「2005/03/04」が表示される。
以上の処理により、サーバ1とクライアント2が相互に同期した。
(第7の実施形態)
次に、クライアントアプリケーションの起動時に、クライアントアプリケーションにより表示される各GUI部品の属性(フォント、背景色など)を変更するための手法について説明する。
ここでは、第1の実施形態で説明したWebアプリケーション及びクライアントアプリケーションの場合を例にとり、クライアントアプリケーションにより表示される各GUI部品の属性(フォント、背景色など)を変更するための機能及び処理動作について説明する。
図36は、Webアプリケーションの構成例を示したものである。なお、図36において、第1の実施形態で説明した図12のWebアプリケーションと同一部分には同一符号を付している。
図37は、クライアントアプリケーションの構成例を示したものである。なお、図37において、第1の実施形態で説明した図13のクライアントアプリケーションと同一部分には同一符号を付している。
図36及び図37において、第1の実施形態と異なる点は、図36及び図37では、GUI部品の属性を、当該GUI部品に対応するタグに対応付けるための機能が追加されている。
ここでは、具体例としては、コンポーネント(JLabel)301hに対応するGUI部品の前景色「foreground」属性と、当該コンポーネントに対応するUIコンポーネント(UIJLabel)401hにより生成されるタグの属性「foreground」と定義する。
このために、UIコンポーネント(UIJLabel)401hのタグクラスとTLD(Tag Library Description)ファイルに、「foreground」属性を定義することで、Webアプリケーションプログラムが記述されているJSPファイル中のUIコンポーネント(UIJLabel)401hのタグの属性に、「foreground」を記述することが可能となる。
JSFの場合、バッキングビーンズを「bean1」とすると、そのプロパティ「fore (private java.awt.Color fore)」に対して、「foreground=”#{bean1.fore}”」という書式でバリューバインディングすればよい。ただし、JSFや後述のencodeBegin(), encodeEnd()メソッドで「fore」プロパティを取得できるようにするために、「bean1」に「fore」プロパティのゲッターメソッドを用意する必要がある。
ここでは、「fore」プロパティは定数値であり、セッターメソッドはあっても良いが不要である。また、バリューバインディングではなく、文字列で「public static定数(具体例として文字列“java.awt.Color.red”など)」を指定しても良い。
JSFの詳細は、「JavaServer FacesによるWebアプリケーション開発」(川崎克己著、秀和システム、2004、ISBN-4798008303)に記載されている。
なお、本実施形態では、「bean1」の「fore」プロパティが後述の属性データ保持部801に相当する。
図36のWebアプリケーション11において、図12のWebアプリケーション11と異なる点は、図36では、クライアントアプリケーション301に対応する各UIコンポーネント401z、401h〜401jに対し、属性Paramタグ生成部802z、802h〜802jが新たに追加され、さらに、属性データ保持部801も新たに追加されている点である。
各UIコンポーネント401z、401h〜401jに対応する各属性Paramタグ生成部802z、802h〜802jは、ブラウザ12からのリクエストを受けて実行される、(6)Render Responseフェーズにおいて、当該UIコンポーネントの識別子と属性名、及び属性データ保持部801に保持されている属性の定数値を含むParamタグを生成する。
以下、各UIコンポーネント401z、401h〜401jに対応する各属性Paramタグ生成部802z、802h〜802jを区別する必要がない場合には、属性Paramタグ生成部802と呼ぶ。
Paramタグは、UIコンポーネントの識別子と属性とその定数値を表現できる書式であればどのようなものであっても良い。また、Paramタグ生成部802は、リクエスト元がブラウザ12の場合に限らず、クライアントアプリケーションの場合でも、(6)Render Responseフェーズで、上記Paramタグを出力しても良い。この場合、クライアントアプリケーションもParamタグを含むレスポンスを受信するが、クライアントアプリケーションはParamタグを認識しないため誤動作は発生しない。
属性Paramタグ生成部802は、(6)Render Responseフェーズにおいて、encodeBegin()メソッドもしくはendcodeEnd()メソッドで、属性データ保持部801に記憶されている属性の定数値と、UIコンポーネントの識別子を取得し、後述のようなParamタグを出力する。
以下の説明では、UIJLabel401hに対応するGUI部品201hの「foreground」属性を変更する場合を例にとり説明する。この場合、UIJLabel401hに対応する属性Paramタグ生成部802hが、「foreground」属性のParamタグを生成する。生成されるParamタグは、例えば、<Param name=l1 value=foreground,n, 文字列への変換後の定数値>である。ここで、nは、定数値を文字列に変換するためのルール番号を指定する。定数値を文字列に変換するためには、(a)定数値がStringオブジェクトなので変換の必要なし、(b)定数値が直列化可能なため定数値を直列化した上でBase64によって文字列に変換する、(c)文字列でpublic static定数を指定する(例えば、文字列“java.awt.Color.red“など)、(d)独自の変換ルール、などのように複数の変換方式が考えられる。
そこで、変換方式と数値nを予め対応付けしておくことで、どのような変換を行なったかをクライアント側に通知する。クライアントアプリケーションは、上述のnによって特定される変換ルールの逆変換を行なうことで元の定数値を取得可能となる。
図37クライアントアプリケーション301において、図13のWebアプリケーション301と異なる点は、図37において、属性Paramタグ適用部310が新たに追加されている。
属性Paramタグ適用部310は、クライアントアプリケーション起動後に、上述のParamタグから属性とその定数値を取得し、必要に応じて定数値を復元し、当該Paramタグ内の識別子に対応するGUI部品に、当該属性の定数値を適用する機能を有する。
図38は、サーバ1とクライアント2との間の処理手順を示したものである。なお、図38において、図14と同一部分には同一符号を付し、異なる部分について説明する。
すなわち、図38では、図14のステップP12、ステップP17、ステップP47、ステップP52の処理動作が異なる。
図38のステップP12において、Webアプリケーション11が、GETリクエストを受信すると、(6)Render Responseフェーズにおいて、属性Paramタグ生成部802hは、属性データ保持部801に保持されている定数値(java.awt.Color.redオブジェクト)を取得する(ステップP12b)。そして、(例えば「foreground」属性を赤色とする)Paramタグをクライアントアプリケーション起動命令タグのサブタグとして生成する(ステップP12c)。ステップP13では、当該Paramタグを含むレスポンスをクライアントへ送信する。
当該Paramタグを含むレスポンスを受信したブラウザ12は、ステップP15及びステップP16を経て、ステップP17において、クライアントアプリケーション301を起動する(ステップP17a)。
ステップP17において、クライアントアプリケーションが起動されると、属性Paramタグ適用部310が、上記Paramタグ内の識別子に対応するGUI部品201hの、当該Paramタグにより指定された属性を、当該Paramタグで指定された値(前景色を赤色)に設定する(ステップp7c)。これにより、図15のユーザインタフェース上のGUI部品201h、すなわち、文字列「日付」の文字の色が赤色に更新される。
ステップP47においても上記ステップP12と同様である。すなわち、(6)Render Responseフェーズにおいて、属性Paramタグ生成部802hは、属性データ保持部801に保持されている定数値(java.awt.Color.redオブジェクト)を取得する(ステップP47b)。そして、(例えば「foreground」属性を赤色とする)Paramタグをクライアントアプリケーション起動タグのサブタグとして生成する(ステップP12c)。ステップP48では、当該Paramタグを含むレスポンスをクライアントへ送信する。
ステップP52においても上記ステップP17と同様である。すなわち、クライアントアプリケーションが起動されると、属性Paramタグ適用部310が、上記Paramタグ内の識別子に対応するGUI部品201hの、当該Paramタグにより指定された属性を、当該Paramタグで指定された値(前景色を赤色)に設定する(ステップP52c)。これにより、図16のユーザインタフェース上のGUI部品201h、すなわち、文字列「日付」の文字の色が赤色に更新される。
なお、属性Paramタグ適用部310に、予めJLabel301hに対し、「foreground」属性のセッターメソッドsetForeground(java.awt.Color)を登録しておくことで、上記Paramタグから抽出した「foreground」属性の属性値をGUI部品の上記セッターメソッド経由でJLabel301hに適用することで、GUI部品201h、すなわち、文字列「日付」の文字の色が赤色に更新することができる。
また、GUI部品のBeanInfoが保持するGUI部品の属性と、そのセッターメソッドの組み合わせを機械的に抽出し、予め属性Paramタグ適用部310に登録しておくことでも実現可能である。
以後の実施形態においても、クライアントアプリケーションの属性Paramタグ適用部310が、上記のように、GUI部品の属性と、そのセッターメソッドの組み合わせを登録をしておくことで、レスポンス内の属性値を用いて、GUI部品の属性を変更することが可能である。
なお、上記説明は、第1の実施形態のWebアプリケーション及びクライアントアプリケーションの場合を例にとり説明したが、第2〜第6の実施形態のWebアプリケーション及びクライアントアプリケーションに対しても、上記同様にして、クライアントアプリケーションにより表示される各GUI部品の属性(フォント、背景色など)を変更することができる。
すなわち、Webアプリケーション11に、属性データ保持部801と、クライアントアプリケーション301の各GUI部品に対応する各UIコンポーネントに対し、属性Paramタグ生成部802を追加する。また、クライアントアプリケーション301に、属性Paramタグ適用部310を追加する。
さらに、Webアプリケーション11の(6)Render Responseフェーズの処理で、属性Paramタグ生成部802は、属性データ保持部801から、属性の定数値を取得して、GUI部品の識別子と属性名と属性値を含むParamタグを生成し、当該Paramタグを含むレスポンスをクライアントへ送信する。
ブラウザ12は、クライアントアプリケーションを起動、もしくは再起動した後に、属性Paramタグ適用部310が、当該Paramタグ内の属性値を、対応するGUI部品に設定する。
このような機能及び処理動作により、前述の第2〜第6の実施形態のクライアントアプリケーションは、GUI部品201hの文字の色を赤色に変更することができる。
(第8の実施形態)
クライアント1において、ユーザ操作により、Webアプリケーションへ送信した値を用いて、(5)Invoke Applicationフェーズで、ビジネスロジックを実行し、その結果に応じてクライアントアプリケーションにより表示されるGUI部品の属性(色、フォントなど)を変更するための手法について説明する。
図39は、Webアプリケーションの構成例を示したものである。なお、図39において、第1の実施形態で説明した図12のWebアプリケーション、第7の実施形態で説明した図36のWebアプリケーションと同一部分には同一符号を付している。
図40は、クライアントアプリケーションの構成例を示したものである。なお、図40において、第1の実施形態で説明した図13のクライアントアプリケーション、第7の実施形態で説明した図37のクライアントアプリケーションと同一部分には同一符号を付している。
第7の実施形態では、GUI部品の属性値は、常に同じであったが、第8の実施形態では、属性値が変更可能になっている。
JSFの場合は、バリューバインディングされたプロパティを変更可能にするために、当該プロパティに対応するセッターメソッドをバッキングビーンズに用意する必要がある。以下、本実施形態では、クライアントアプリケーション301のUIコンポーネント(JLabel)301xの属性「text」と、それに対応するWebアプリケーション11のUIコンポーネント(UIJLabel)401xの属性「text」とを例にとり説明する。
図39のWebアプリケーション11において、図36のWebアプリケーション11と異なる点は、図39では、UIコンポーネントツリー101aに、UIコンポーネント(UIJLabel)401hの他に、属性値の変動するUIコンポーネント(UIJLabel)401xが追加されている。これに伴い、UIコンポーネント(UIJLabel)401xに対応する属性Paramタグ生成部804xも追加されている。
また、クライアントから送信された値に応じて属性データ保持部801に記憶されている属性値を変更するビジネスロジック805が新たに追加されている。
以下、各UIコンポーネント401z、401h〜401j、401xに対応する各属性変数Paramタグ生成部802z、802h〜802j、802xを区別する必要がない場合には、属性変数Paramタグ生成部802と呼ぶ。
属性データ保持部801に記憶されている属性値は、クライアント2から送信された値に応じて、(5)Invoke Applicationフェーズで実行されるビジネスロジック805によって変更される。
属性Paramタグ生成部802は、ブラウザ12からのリクエストを受けて実行される、(6)Render Responseフェーズにおいて、当該UIコンポーネントの識別子と属性名、及び属性データ保持部802に記憶されている属性値を含むParamタグを生成する。
属性データ保持部802は、データ保持部102同様、バッキングビーンズのプロパティが相当し、バッキングビーンズのプロパティに変動値を定義した(GUI部品に対応する)UIコンポーネントの属性をバリューバインディングすることで、(6)Render Responseフェーズで、第7の実施形態と同じ形式のParamタグを出力する。
コンポーネント(JLabel)301hの属性「text」とそれに対応するUIコンポーネント(UIJLabel)401hの属性「text」を例にすると、バッキングビーンズ「bean2」に定義されたStringプロパティ「str」に対し、バリューバインディングは「text=”#{bean2.str}”」と表すことができる。なお、バッキングビーンズのプロパティは第7の実施形態のように、定数ではなく変数であるため、バッキングビーンズの該プロパティには、ゲッターメソッドに加えてセッターメソッドを用意する必要がある。
図40のクライアントアプリケーション301において、図37のクライアントアプリケーション301と異なる点は、図40では、コンポーネントツリー301aに、コンポーネント(JLabel)301hの他に、クライアント2のユーザへのメッセージを表示するための、属性値の変動するUIコンポーネント(JLabel(2))301xが追加されている。
属性Paramタグ適用部310は、クライアントアプリケーション起動後に、上述のParamタグから属性名とその値を取得し、当該Paramタグ内の識別子に対応するGUI部品に、当該属性の値を適用する機能を有する。
図41は、サーバ1とクライアント2との間の処理手順を示したものである。なお、図41において、図38と同一部分には同一符号を付し、主に異なる部分について説明する。
まず、図41のステップP12において、Webアプリケーション11が、GETリクエストを受信すると、(6)Render Responseフェーズにおいて、属性Paramタグ生成部802xは、属性データ保持部801(bean2の「str」属性)から、属性値を取得する(ステップP12b)。「str」属性の初期値は文字列“ ”であるものとする。そして、取得した属性値、(ここでは、初期値の“ ”)を含むParamタグをクライアントアプリケーション起動タグのサブタグとして生成する(ステップP12c)。ステップP13では、当該Paramタグを含むレスポンスをクライアントへ送信する。
当該Paramタグを含むレスポンスを受信したブラウザ12は、ステップP15及びステップP16を経て、ステップP17において、クライアントアプリケーション301を起動する(ステップP17a)。
ステップP17において、クライアントアプリケーションが起動されると、属性Paramタグ適用部310が、上記Paramタグ内の識別子に対応するGUI部品(UIコンポーネント(JLabel(2))301x)の、当該Paramタグにより指定された属性を、当該Paramタグで指定された値に設定する(ステップP7c)。ここでは、属性値は“ ”であるから、表示される文字列はない。従って、図15に示したようなユーザインタフェースが表示される。
続いて、ユーザが、図15の入力テキストフィールド201iに、文字列「2005/03/04」を入力し、取得ボタン201jを押下すると(ステップP18)、UIコンポーネント(JTextField)301iの識別子「tf1」と、入力値「2005/03/04」とを示すリクエスト・パラメータ「tf1=2005/03/04」を含むPOSTリクエストが、Webアプリケーション11へ送信される(ステップP42)。
サーバ1のWebアプリケーション11では、当該POSTリクエストを受信すると、以下に示すような処理が行われる(ステップP43)。すなわち、図6に示した一連の処理動作が行われる。
このとき、(4)Update Model Valuesフェーズでは、UIJTextField401iは、データ保持部102に、当該POSTリクエスト中のリクエストパラメータ内の値「2005/03/04」を記憶することで、クライアント2のブラウザ上への新たなデータの入力に対応して、サーバ1のデータ保持部102で保持すべきデータが更新された。すなわち、サーバ1がクライアント2に同期した(ステップP43a)。なお、ステップP43aの処理は、第1の実施形態と同様である。
第8の実施形態では、次の(5)Invoke Applicationフェーズにおいて、ビジネスロジック805が実行される。
図42は、ビジネスロジック805の処理動作を示すフローチャートである。ビジネスロジック805は、当該POSTリクエストの送信日時が予め定められた期限内であるときには、属性データ保持部801の属性値(bean2の「str」属性の値)を“ ”に変更し(ステップT01、ステップT102)、当該送信日時が当該期限を越えているときには、属性データ保持部801の属性値(bean2の「str」属性の値)を“期限内に申請してください”に変更する(ステップT01、ステップT103)。
ここでは、当該POSTリクエストの送信日時が当該期限を越えているとする。従って、ビジネスロジック805は、属性データ保持部801の属性値(bean2の「str」属性の値)を初期値“ ”から“期限内に申請してください”に更新する(ステップP43b)。
そして、(6)Render Responseフェーズにおいて、各UIコンポーネントはHTMLタグエレメントを出力し、レスポンスを生成する。このとき、図15のリストボックス201mを生成する、図39のHtmlSelectManyListbox101mは、データ保持部102に既に登録済みの日付「2005/02/18」と、データ保持部102の更新により新たに登録された日付「2005/03/04」を取得して、それらを要素とするリストボックスを生成する。ステップP44では、Webアプリケーション11で生成されたレスポンスがクライアント2へ返信される。
当該レスポンスを受け取ったクライアントアプリケーション301のGETリクエスト送信命令部305は、ブラウザ12に再度GETリクエストを送信させる(ステップP45、ステップP46)。
当該GETリクエストを受信したWebアプリケーション11では、上記ステップP12と同様、図6に示した一連の処理動作が行われる(ステップP47)。このとき、(6)Render Responseフェーズにおいて、属性Paramタグ生成部802xは、属性データ保持部801(bean2の「str」属性)から、更新された属性値を取得する(ステップP47b)。「str」属性の更新後の値は“期限内に申請してください”である。そして、取得した属性値を含むParamタグ(クライアントアプリケーション起動タグのサブタグ)を生成する(ステップP47c)。ステップP48では、当該Paramタグを含むレスポンスをクライアントへ送信する。
当該Paramタグを含むレスポンスを受信したブラウザ12は、ステップP50及びステップP51を経て、ステップP52において、クライアントアプリケーション301を起動する(ステップP52a)。
ステップP52において、クライアントアプリケーションが起動されると、属性Paramタグ適用部310が、上記Paramタグ内の識別子に対応するGUI部品、すなわち、UIコンポーネント(JLabel(2))301xの、当該Paramタグにより指定された属性を、当該Paramタグで指定された値に設定する(ステップP52c)。ここでは、JLabel(2)301xの属性値は、“期限内に申請してください”であるから、図43に示すように、ユーザインタフェース上に、文字列201x、すなわち、“期限内に申請してください”が表示される。なお、この文字列201xの文字の色は、クライアントアプリケーション301の開発時に予め指定しておいても良いし、第7の実施形態で説明した手法を用いて、文字の色を設定してもよい。
なお、上記説明は、第1の実施形態のWebアプリケーション及びクライアントアプリケーションの場合を例にとり説明したが、第5、第6の実施形態のWebアプリケーション及びクライアントアプリケーションに対しても、上記同様にして、クライアントアプリケーションにより表示される各GUI部品の属性(表示する文字列、フォント、背景色など)を、クライアント2のユーザ操作に応じて変更することができる。
すなわち、Webアプリケーション11に、属性データ保持部801と、ビジネスロジック805、クライアントアプリケーション301に対応する各UIコンポーネントに対し、属性Paramタグ生成部802を追加する。また、クライアントアプリケーション301に、属性Paramタグ適用部310を追加する。
さらに、Webアプリケーション11の(5)Invoke Applicationフェーズで、ビジネスロジック805を実行して、属性データ保持部801に記憶されている属性値を更新する。また、(6)Render Responseフェーズの処理で、属性Paramタグ生成部802は、属性データ保持部801から、属性の値を取得して、UIコンポーネントの識別子と属性名と属性値を含むParamタグを生成し、当該Paramタグを含むレスポンスをクライアントへ送信する。
ブラウザ12は、クライアントアプリケーションを起動、もしくは再起動した後に、属性Paramタグ適用部310が、当該Paramタグ内の属性値を、対応するUIコンポーネントに適用することで、クライアントアプリケーション301に属性の値を設定する。
(第9の実施形態)
前述の第8の実施形態では、主に第1の実施形態のWebアプリケーション及びクライアントアプリケーションの場合を例にとり、Paramタグを用いて、GUI部品の属性値を通知する場合を説明した。
次に、第2の実施形態のWebアプリケーション及びクライアントアプリケーションの場合を例にとり、コメントタグを用いて、GUI部品の属性値(色、フォントなど)を通知する場合について説明する。
図44は、Webアプリケーションの構成例を示したものである。なお、図44において、第2の実施形態で説明した図17のWebアプリケーション、第8の実施形態で説明した図39のWebアプリケーションと同一部分には同一符号を付している。
図45は、クライアントアプリケーションの構成例を示したものである。なお、図45において、第2の実施形態で説明した図18のクライアントアプリケーション、第8の実施形態で説明した図40のクライアントアプリケーションと同一部分には同一符号を付している。
前述の第8の実施形態と同様、JSFの場合には、バリューバインディングされたプロパティを変更可能にするために、当該プロパティに対応するセッターメソッドをバッキングビーンズに用意する必要がある。
以下、本実施形態では、クライアントアプリケーション301のコンポーネント(JLabel(3))601yの属性「text」と、それに対応するWebアプリケーション11のUIコンポーネント(UIJLabel(3))401yの属性「text」とを例にとり説明する。
図44のWebアプリケーション11において、図17のWebアプリケーション11と異なる点は、図44では、UIコンポーネントツリー101aに、属性値の変動するUIコンポーネント(UIJLabel(3))401yが追加されている。また、図44では、クライアントアプリケーション301に対応する各UIコンポーネント401z、401h〜401j、401l、401m、401yに対し、属性コメントタグ生成部806z、806h〜806j、806m、806yが新たに追加され、さらに、属性データ保持部801、ビジネスロジック805も新たに追加されている。
以下、各UIコンポーネント401z、401h〜401j、401l、401m、401yに対応する各属性コメントタグ生成部806z、806h〜806j、806m、806yを区別する必要がない場合には、属性コメントタグ生成部806と呼ぶ。
属性コメントタグ生成部806は、クライアントアプリケーション301からのリクエストを受けて実行される、(6)Render Responseフェーズにおいて、当該属性コメントタグ生成部806に対応するUIコンポーネントの識別子と属性名、及び属性データ保持部801に保持されている属性の定数値を含むコメントタグを生成する。
属性データ保持部801、ビジネスロジック805については、前述の第8の実施形態と同様である。
属性データ保持部801は、データ保持部801と同様に、バッキングビーンズのプロパティが相当し、バッキングビーンズのプロパティに変動値を定義したGUI部品に対応するUIコンポーネントの属性をバリューバインディングすることで、(6)Render Responseフェーズにおいて、当該GUI部品の識別子と属性名、変換ルール番号、変換後の値をコメントタグに挿入して出力する。生成されるコメントタグは、例えば、<!−−jl3=text,n,変換後の文字列 −−>である。
JLabel601yの属性「text」とそれに対応するUIJLabel401yの属性「text」を例にとすると、バッキングビーンズ「bean2」に定義されたStringプロパティ「str」に対し、バリューバインディングは、text=”#{bean2.str}”と表される。なお、バッキングビーンズのプロパティは定数ではなく変数であるため、バッキングビーンズの該プロパティにはゲッターメソッドに加えてセッターメソッドを用意する必要がある。
図45のクライアントアプリケーション301において、図18のクライアントアプリケーション301と異なる点は、図45において、コンポーネントツリー301aには、属性値の変動するUIコンポーネント(JLabel(3))601yが追加されている。JLabel(3)601yは、Webアプリケーション11のUIコンポーネント(UIJLabel)401yに対応する。また、属性コメントタグ適用部311が新たに追加されている。
属性コメントタグ適用部311は、クライアントアプリケーション起動後に、上述のコメントタグから属性とその値を取得し、当該コメントタグ内の識別子に対応するGUI部品に、当該属性の値を適用する機能を有する。すなわち、属性コメントタグ適用部311は、コメントタグにより指定されたGUI部品の指定された属性を、指定された値に更新する。その際、必要に応じてnで指定された変換ルールの逆返変換を行なうことで属性の変更後の値を復元する。
図46は、サーバ1とクライアント2との間の処理手順を示したものである。なお、図46において、図19と同一部分には同一符号を付し、主に異なる部分について説明する。
第2の実施形態と同様、ステップP11〜ステップP17までの処理により、ブラウザ12上に、図20に示すようなユーザインタフェースが表示される。
ユーザが、図20の入力テキストフィールド201iに、文字列「2005/03/04」を新たに入力し、取得ボタン201jを押下すると、UIコンポーネント(JTextField)301iの識別子「tf1」と、入力された文字列「2005/03/04」有するリクエスト・パラメータ「tf1=2005/03/04」を含むPOSTリクエストが、通信部302からサーバ1へ送信される(ステップP18、ステップP41、ステップP42)。
サーバ1では、当該POSTリクエストを受信すると、図6に示した一連の処理動作を行う(ステップP43)。すなわち、第2の実施形態と同様、(4)Update Model Valuesフェーズにおいて、当該リクエスト中のリクエスト・パラメータに含まれている識別子と同一の識別子をもつUIコンポーネント(UIJTextField)401iが、当該リクエスト・パラメータから、値「2005/03/04」を取得し、この値をデータ保持部102に記憶する(ステップP43a)。この結果、クライアント2のブラウザ上への新たなデータの入力に対応して、サーバ1のデータ保持部102で保持すべきデータが更新された。すなわち、サーバ1がクライアント2に同期した。
また、第9の実施形態では、次の(5)Invoke Applicationフェーズにおいて、ビジネスロジック805が実行される。
ビジネスロジック805は、例えば、第8の実施形態と同様、図42に示したような処理動作を行う。ここでは、当該POSTリクエストの送信日時が当該期限を越えているとする。従って、ビジネスロジック805は、属性データ保持部801の属性値(「bean2」の「str」属性の値)を初期値“ ”から“期限内に申請してください”に更新する(ステップP43c)。
そして、(6)Render Responseフェーズにおいて、UIJLabel(3)401yの属性コメントタグ生成部806yが属性データ保持部102(「bean2」の「str」属性)から該更新された値 “期限内に申請してください” 取得して(ステップP43d)、該属性値を含むコメントタグ(属性コメントタグ)を生成する(ステップP43e)。
一方、(6)Render Responseフェーズでは、第2の実施形態と同様、各UIコンポーネントはHTMLタグエレメントを出力する。このとき、図20のリストボックス201mに対応するUIコンポーネント(UIJList)501mは、データ保持部102から、リストボックスに表示すべき値を全て取得し、取得した値と当該UIコンポーネント(UIJList)501mの識別子がコメントとして挿入されたコメントタグ、例えば、<!−lst1=2005/02/18,2005/03/04−>を生成する(ステップP43e)。
上記ステップP43eで生成された属性コメントタグ、及びステップP43dで生成されたコメントタグを含むレスポンスが、クライアント2へ返信される(ステップP61)。
上記レスポンスをクライアント2の通信302を介して受信したクライアントアプリケーション301は、第2の実施形態と同様、そのレスポンスを、レスポンス適用部306に渡す(ステップP62)。当該レスポンスを受け取ったレスポンス適用部306は、当該レスポンス中のコメントタグに、クライアントアプリケーション301中のUIコンポーネントのいずれかの識別子が含まれているときには、当該コメントタグから、当該識別子(ここでは、UIJList501mの識別子「lst1」)とともに書き込まれている値(ここでは、「2005/02/18」、「2005/03/04」)を取り出す(ステップP63)。そして、この取り出された値を、当該識別子「lst1」に対応するGUI部品であるリストボックス201mにセットする(表示させる)。すなわち、「2005/02/18」及び「2005/03/04」が、リストボックス201mに表示される(ステップP64)。
以上の処理手順により、サーバ1で更新されたデータ保持部102の内容が、クライアント2のブラウザ上に反映され、クライアント2がサーバ1に同期することとなった。
第9の実施形態では、さらに、上記レスポンスを受信したクライアントアプリケーション301の属性コメントタグ適用部311が、当該レスポンスから属性コメントタグを抽出する(ステップP65)。そして、属性コメントタグ内の属性値を必要に応じて復元し(ステップP66)、当該属性コメントタグ内の識別子に対応するGUI部品の属性値を更新する(ステップP67)。ここでは、UIコンポーネントJLabel(3)601yに対応するGUI部品201yの属性値が更新される。すなわち、図20のように、GUI部品201yが表示されていない状態から、図47に示すように、“期限内に申請してください”という文字列のGUI部品201yが表示される。
なお、上記説明は、第2の実施形態のWebアプリケーション及びクライアントアプリケーションの場合を例にとり説明したが、第4の実施形態のWebアプリケーション及びクライアントアプリケーションに対しても、上記同様にして、クライアントアプリケーションにより表示される各GUI部品の属性(表示する文字列、フォント、背景色など)を、クライアント2のユーザ操作に応じて変更することができる。
すなわち、Webアプリケーション11に、属性データ保持部801と、ビジネスロジック805、クライアントアプリケーション301に対応する各UIコンポーネントに対し、属性コメントタグ生成部806を追加する。また、クライアントアプリケーション301に、属性コメントタグ適用部311を追加する。
さらに、Webアプリケーション11の(5)Invoke Applicationフェーズで、ビジネスロジック805を実行して、属性データ保持部801に記憶されている属性値を更新する。また、(6)Render Responseフェーズの処理で、属性コメントタグ生成部806は、属性データ保持部801から、属性の値を取得して、UIコンポーネントの識別子と属性名と属性値を含むコメントタグを生成し、当該コメントタグを含むレスポンスをクライアントへ送信する。
クライアントアプリケーション301は、当該レスポンスを受信すると、属性コメントタグ適用部310が、当該コメントタグ内の属性値を、対応するGUI部品に適用する。
上記第1乃至第9の実施形態では、クライアントアプリケーションにより、ユーザインタフェース上に1つの入力インタフェースが表示される場合について説明したが、この場合に限らず、クライアントアプリケーションにより、ユーザインタフェース上に複数の入力インタフェースが表示される場合でも適用可能である。
また、上記第7乃至第9の実施形態では、1つのGUI部品に対し、その属性を変更する場合を例にとり説明したが、同時に複数のGUI部品の属性を変更することも、全く同様にして行うことができる。
本発明の実施の形態に記載した本発明の手法は、コンピュータに実行させることのできるプログラムとして、磁気ディスク(フレキシブルディスク、ハードディスクなど)、光ディスク(CD−ROM、DVDなど)、半導体メモリなどの記録媒体に格納して頒布することもできる。
なお、本発明は上記実施形態そのままに限定されるものではなく、実施段階ではその要旨を逸脱しない範囲で構成要素を変形して具体化できる。また、上記実施形態に開示されている複数の構成要素の適宜な組み合わせにより、種々の発明を形成できる。例えば、実施形態に示される全構成要素から幾つかの構成要素を削除してもよい。さらに、異なる実施形態にわたる構成要素を適宜組み合わせてもよい。