この章では、ナビゲーション・ルールおよびナビゲーション・ケースの作成方法と、結果を使用してナビゲーション・ルールをトリガーする基本ナビゲーション・コンポーネント(ボタン、リンクなど)の作成方法について説明します。
この章の内容は次のとおりです。
動的ナビゲーション・メニューの作成方法は、第19章「複雑なUIコンポーネントの使用」を参照してください。
JSFアプリケーションでのナビゲーションは、ナビゲーション・ルールによって定義されます。これらのルールは、UIコンポーネントによって指定される結果に基づき、UIコンポーネントがクリックされた直後に表示されるページを決定します。
アプリケーションに対するページ・ナビゲーションの定義は、次のような2段階プロセスです。
最初に、アプリケーション内のすべてのページについてナビゲーション・ルールを作成します。
ほとんどの場合、アプリケーションのページごとに1つのルールを定義します。しかし、ページのグループに作用するパターンベースのルールまたはすべてのページに作用するグローバル・ルールを定義することもできます。
次に、ページ上の各ナビゲーション・コンポーネント(コマンド・ボタン、コマンド・リンクなど)で、action
属性で静的結果値または動的結果値のいずれかを指定します。
静的結果値とは、ナビゲーション・ルールに定義される特定の結果への明示的な参照です。動的結果値とは、結果値を戻すバッキングBeanメソッドのバインディングから導出されます。いずれの場合も、action
属性に指定される結果値は、ナビゲーション・ルールに定義された結果と一致するか、発生するナビゲーションのデフォルトのナビゲーション・ルールによって処理される必要があります。
単純なページ間のナビゲーション・リンクをハードコーディングして作成することはできますが、結果およびナビゲーション・ルールを使用すると、アプリケーションのナビゲーションの定義および変更がずっと簡単になります。
この章では次の内容について説明します。
ナビゲーション・ルールおよびナビゲーション・ケースの概要とその作成方法
グローバル・ルール、パターンベース・ルールおよびデフォルト・ルールの作成方法
静的結果値を使用するUIコンポーネントの作成方法
動的結果値を戻すバッキングBeanへのナビゲーション・コンポーネントのバインディング方法
JavaServer Facesでは、アプリケーション・ページ間のナビゲーションは、一連のルールによって定義されます。ナビゲーション・ルールは、ユーザーがナビゲーション・コンポーネント(ボタン、ハイパーリンクなど)をクリックしたときに表示される次のページを決定します。
ナビゲーション・ルールは、あるページから1つ以上の他のページへのナビゲーションを定義します。各ナビゲーション・ルールは、ユーザーがそのページからどこに移動できるかを定義する1つ以上のケースを保持できます。たとえば、ページにアプリケーション内の他のページへのリンクが複数ある場合、そのページに対する単一のナビゲーション・ルールと、他のページへのリンクごとに1つのナビゲーション・ケースを作成できます。ルール自体は、次の場所からのナビゲーションを定義できます。
ナビゲーション・ルール定義は、JSF構成ファイル(faces-config.xml
)に格納されます。ルールは構成ファイルに直接定義できます。あるいは、JDeveloperのJSFナビゲーション・モデラーおよびJSF構成エディタを使用できます。ナビゲーション・モデラーおよび構成エディタの使用をお薦めします。その理由は次のとおりです。
アプリケーション・ページ間のナビゲーションをモデル化および編集するためのGUI環境が装備されています。
ページおよびナビゲーション・リンクの視覚的な図を使用してアプリケーション・ナビゲーションを設計できます。
ナビゲーション・モデラーを使用して、最初に特定のページからアプリケーション内の1つ以上の他のページへのナビゲーション・ルールを作成します。構成エディタを使用して、複数のページに対するグローバル・ルールまたはパターンベース・ルールの作成、デフォルトのナビゲーション・ケースの作成およびナビゲーション・ルールの編集を行います。
faces-config.xml
ファイルでナビゲーション・ルールを定義する要素を理解しておくと、ナビゲーション・モデラーおよび構成エディタを使用してルールを作成する、または直接構成ファイルでルールを作成する際に役立ちます。例16-1に、faces-config.xml
ファイルでのJSFナビゲーション・ルール要素の一般的な構文を示します。
例16-1 faces-config.xmlファイルでのJSFナビゲーション・ルールの構文
<navigation-rule> <from-view-id>page-or-pattern</from-view-id> <navigation-case> <from-action>action-method</from-action> <from-outcome>outcome</from-outcome> <to-view-id>destination-page</to-view-id> <redirect/> </navigation-case> <navigation-case> ... </navigation-case> </navigation-rule>
ナビゲーション・ルールは、次の要素で構成されます。
from-view-id
: 完全なページ識別子(ページへの状況依存の相対パス)またはアスタリスク(*)のワイルドカード文字で終わるページ識別子の接頭辞が含まれる任意の要素。ワイルドカード文字を使用すると、ルールはワイルドカード・パターンと一致するすべてのページに適用されます。すべてのページに適用されるグローバル・ルールを作成するには、この要素を空白のままにします。
navigation-case
: ナビゲーション・ルールの各ケースの必須ラッパー要素。各ケースは、同じページからの異なるナビゲーション・パスを定義します。ナビゲーション・ルールには、少なくとも1つのナビゲーション・ケースが必要です。
from-action
: ルールの適用を指定されたアクション・メソッドからの結果のみに制限する任意の要素。アクション・メソッドは、ELバインディング式として指定されます。たとえば、#{backing_SRCreate.cancelButton_action}
などです。
from-outcome
: UIコンポーネントのaction
属性に指定された値と照合される結果値が含まれる必須要素。後ほど、UIコンポーネントで結果値を明示的にまたはアクション・メソッドの戻り値から動的に参照する方法について説明します。
to-view-id
: ルールが実行されるときにナビゲーションのルーティング先となるページの完全なページ識別子が含まれる必須要素。
redirect
: 現在リクエストに対するレスポンスとして、レンダリングするかわりに、リダイレクト・レスポンスを介して新しいビューがリクエストされることを示す任意の要素。この要素に値は必要ありません。(詳細は、16.2.2項「ナビゲーション・ルールの作成時に発生する処理」を参照してください。)
ナビゲーション・ルールの作成の起点として、JDeveloperのJSFナビゲーション・モデラーを使用します。ナビゲーション・モデラーは、アプリケーション・ページと、それらのページに対するナビゲーション・ケースを作成するためのビジュアル・モデリング・ツールです。
ナビゲーション・モデラーを使用して基本ナビゲーション・ルールを作成した後に、JSF構成エディタまたは直接ナビゲーション・モデラーでルールを編集できます。作成するJSF構成ファイルごとに1つのナビゲーション・モデラー・ダイアグラムがあります。
JSFナビゲーション・モデラーを使用してナビゲーション・ルールを定義する手順:
アプリケーション・ナビゲータで、WEB-INF
ディレクトリにあるfaces-config.xml
ファイルをダブルクリックして、構成ファイルをビジュアル・エディタに表示します。
ビジュアル・エディタで、「ダイアグラム」タブをクリックし、図16-1に示すナビゲーション・モデラーを表示します。
コンポーネント・パレットには、JSFナビゲーション・モデラーのコンポーネントが自動的に表示されます。
次のいずれかの方法で、アプリケーション・ページをダイアグラムに追加します。
ページを新規作成するには、JSF Pageをコンポーネント・パレットからダイアグラムにドラッグします。ダイアグラムでページ・アイコンをダブルクリックし、JSF JSPの作成ウィザードを表示します。このウィザードでは、ページに名前を付け、ページの特性を定義できます。
既存のページをダイアグラムに追加するには、そのページをアプリケーション・ナビゲータからダイアグラムにドラッグします。
ヒント: ダイアグラム全体のサムネイルは、構造ウィンドウの「サムネイル」・タブをクリックすると表示できます。 |
次の方法で、ページ間のナビゲーション・ケースを作成します。
ダイアグラムで、ソース・ページのアイコンをクリックした後、宛先ページのアイコンをクリックします。
図16-2に示すように、2つのページ間の実線の矢印として、ナビゲーション・ケースがダイアグラムに描画されます。
矢印は、ナビゲーション・ケースの方向を示します。デフォルトのfrom-outcome
値が矢印のラベルとして表示されます。ソース・ページに対するナビゲーション・ルールが自動的に作成され、宛先ページを参照するデフォルトのナビゲーション・ケースが追加されます。ページが複数のナビゲーション・ケースのソース(たとえば、複数の他のページへのリンクを示すページなど)である場合は、ソース・ページに対して1つのルールが作成され、複数のケースがそのルールに追加されます。
ダイアグラムで、ナビゲーション・ケースを表す矢印をダブルクリックし、図16-3に示す「navigation-caseのプロパティ」ダイアログを表示します。
「navigation-caseのプロパティ」ダイアログを使用して、ナビゲーション・ケースに要素を定義します。各要素の説明は、16.2.1.1項「ナビゲーション・ルール要素の概要」を参照してください。
特定のページ間の基本ナビゲーションを定義すると、JSF構成エディタを使用して次の処理を実行できます。
ページ・グループに対するパターンベース・ナビゲーション・ルールの定義
たとえば、アプリケーション内のページ・グループに一連の共通リンク(メニュー・バーからのリンクなど)がある場合、すべてのページに適用されるパターンベース・ルールを作成できます。ワイルドカード・パターンを使用するルールの対象となるページを指定します。ワイルドカード文字(*)は、パターンの最後の項目である必要があります。JSFナビゲーション・ルールにおけるパターンの一般的な用法は、特定のディレクトリ内のすべてのページを指定することです。例16-2に、サンプルのパターンベース・ナビゲーション・ルールを示します。from-view-id
要素には、特定のページ名ではなくパターンが含まれます。このパターンにより、ルールはmanagement
ディレクトリ内のSRで始まる名前のページすべてに適用されます。
すべてのページに適用されるグローバル・ナビゲーション・ルールの定義
たとえば、アプリケーションでは、すべてのページに適用されるルールを1つ定義し、ユーザーをアプリケーションのホーム・ページに戻すことができます。グローバル・ルールを作成する際に、from-view-id
要素を除外して、ルールがすべてのページに適用されるようにします。ページのUIコンポーネントが特定の結果を戻すたびにルールを適用する場合は、必要に応じてfrom-outcome
要素を含めることができます。例16-3に、サンプルのグローバル・ナビゲーション・ルールを示します。このルールでは、ページのコンポーネントが値gohome
を戻すと、ホーム・ページが表示されます。
結果が指定されていないデフォルトのナビゲーション・ケースの定義
たとえば、ナビゲーション・コンポーネントが動的結果(結果が複数の値のいずれかである)を使用して定義されている場合、1つまたは2つの特定の結果に対するナビゲーション・ケースと、その他すべての結果に対するデフォルトのケースを作成します。このようにすると、ナビゲーション・コンポーネントが不測の結果を戻した場合、ページは特定のページに移動します。例16-4に、サンプルのデフォルトのナビゲーション・ルールを示します。このルールでは、ページのコンポーネントが他のナビゲーション・ケースでは処理されない結果を戻すたびに、ホーム・ページが表示されます。
ヒント: デフォルトのナビゲーション・ケースは、コンポーネントがnull 値をaction 属性に指定する場合は適用されません。その場合、ナビゲーションは発生せず、かわりに同じページが再表示されます。 |
既存のルールおよびケースの編集
JSF構成エディタを使用してナビゲーション・ルールを作成する手順:
アプリケーション・ナビゲータで、WEB-INF
ディレクトリにあるfaces-config.xml
ファイルをダブルクリックして、構成ファイルをビジュアル・エディタに表示します。
ビジュアル・エディタで、「概要」タブをクリックし、構成エディタを表示します。
図16-4に示すように、要素リスト(左隅)から「ナビゲーション・ルール」を選択します。
次の方法で、ナビゲーション・ルールを定義します。
「ナビゲーション・ルール」ボックスの右側にある「新規」ボタンをクリックし、「ナビゲーション・ルールの作成」ダイアログを表示します。
次のいずれかの方法で、「ナビゲーション・ルールの作成」ダイアログを使用して、ナビゲーション・ルールのfrom-view-id
要素を指定します。
単一のページに対するルールを作成するには、完全修飾されたページ名を入力するか、ドロップダウン・リストからページを選択します。
パターンと一致する名前を持つページのグループに適用されるパターンベース・ルールを作成するには、アスタリスク(*)のワイルドカード文字を使用するパターンを入力します。
ワイルドカード文字は、パターンの最後に使用する必要があります。たとえば、パターン/app/management/SR*
により、ルールはmanagementディレクトリ内のSRで始まる名前のページすべてに適用されます。JSFナビゲーション・ルールにおけるパターンの一般的な用法は、特定のディレクトリ内のすべてのページを指定することです。
アプリケーション内のすべてのページに適用されるグローバル・ナビゲーション・ルールを作成するには、ドロップダウン・リストから「<グローバル・ナビゲーション・ルール>」を選択します。
グローバル・ナビゲーション・ルールを作成する場合、from-view-id
要素がfaces-config.xml
ファイルから除外されます。
ヒント: グローバル・ナビゲーション・ルールを定義する際に、from-view-id 要素を除外できます。しかし、faces-config.xml ファイルで明確にするために、<from-view-id> * </from-view-id> または<from-view-id>/* </from-view-id> と値を指定できます。これらすべてのスタイルは同じ結果となります。すなわち、ルールはアプリケーション内のすべてのページに適用されます。 |
完了すると、新しいナビゲーション・ルールが構成エディタのナビゲーション・ルールに表示されます。
次の方法で、ナビゲーション・ケースを定義します。
ナビゲーション・ルールのリストから、ナビゲーション・ケースを定義するルールを選択します。
「ナビゲーション・ケース」ボックスの右側にある「新規」ボタンをクリックし、「ナビゲーション・ケースの作成」ダイアログを表示します。
「ナビゲーション・ケースの作成」ダイアログを使用して、ナビゲーション・ケースの要素を指定します。各要素の説明は、16.2.1.1項「ナビゲーション・ルール要素の概要」を参照してください。
ナビゲーション・ケースの宛先を特定するために、to-view-id
値を指定する必要があります。しかし、from-action
要素またはfrom-outcome
要素、あるいはその両方は空のままにすることができます。from-action
要素を空のままにすると、結果が戻される方法に関係なく、ケースは指定された結果に適用されます。from-outcome
要素を空のままにすると、ケースは指定されたアクション・メソッドからのすべての結果に適用されるため、そのメソッドに対してデフォルトのナビゲーション・ケースが作成されます。from-action
要素とfrom-outcome
要素の両方を空のままにすると、ケースはページに対して定義されたその他のルールでは特定できないすべての結果に適用されるため、ページ全体に対するデフォルトのケースが作成されます。
ヒント: ページのナビゲーション・コンポーネントに結果値をすでに定義している場合は、大/小文字も含めfrom-outcome 値をまったく同じ形式で必ず入力してください。 |
JSFナビゲーション・モデラーまたはJSF構成エディタを使用してナビゲーション・ルールを作成すると、ナビゲーション・ルール要素がfaces-config.xml
ファイルに自動的に追加されます。
最初に空のfaces-config.xml
ファイルが作成されるときに、ダイアグラムの詳細情報(レイアウト、注釈など)を保持するダイアグラム・ファイル(faces.config.oxd_faces
)も作成されます。JDeveloperでは、常にこのダイアグラム・ファイルは、faces-config.xml
ファイルとともに保持され、アプリケーションで必要となるすべての設定が保持されます。つまり、バージョニングまたはソース・コントロールを使用する場合は、ダイアグラム・ファイルが表すfaces-config.xml
ファイルだけでなくダイアグラム・ファイル自体も対象となります。
例16-5に、SRDemoアプリケーションのSRCreateページ用のfaces-config.xml
ファイルに定義された2つのケースを持つナビゲーション・ルールを示します。最初のケースでは、アクティブ化されたナビゲーション・コンポーネントのaction
属性に指定された結果がContinue
である場合にSRCreateConfirm
ページに移動します。2番目のケースでは、アクティブ化されたナビゲーション・コンポーネントのaction
属性がdialog:FAQ
である場合にSRFaqページに移動します。結果の接頭辞dialog:
により、to-view-id
要素のページがダイアログとして起動します。ダイアログの作成の詳細は、19.3項「ポップアップ・ダイアログの使用」を参照してください。
例16-5 特定のページに対するナビゲーション・ルール
<navigation-rule> <from-view-id>/app/SRCreate.jspx</from-view-id> <navigation-case> <from-outcome>Continue</from-outcome> <to-view-id>/app/SRCreateConfirm.jspx</to-view-id> </navigation-case> <navigation-case> <from-outcome>dialog:FAQ</from-outcome> <to-view-id>/app/SRFaq.jspx</to-view-id> </navigation-case> </navigation-rule>
例16-6に、SRDemoアプリケーションに定義されているグローバル・ナビゲーション・ルールを示します。このルールでは、ワイルドカード文字をfrom-view-id
要素で使用して、ルールがアプリケーション内のすべてのページに適用されるようにしています。このグローバル・ルールに定義されているケースは、すべてのページに表示される標準メニューからのナビゲーションを処理します。
一部のケースではredirect
要素を使用しています。これにより、JSFはブラウザに新しいページをリクエストするリダイレクト・レスポンスを送信します。ブラウザが新しいページをリクエストすると、新しいページの実際のURLを示すようにブラウザのアドレス・フィールドに表示されるURLが調整されます。ナビゲーション・ケースでredirect
要素を使用しない場合は、新しいページが現在リクエストに対するレスポンスとしてレンダリングされます。つまり、ブラウザのアドレス・フィールドのURLは変化せず、前のページのアドレスが表示されます。ダイレクト・レンダリングは、リダイレクションより速い場合があります。
ナビゲーション・ケースは、リダイレクトとして定義できます。ナビゲーション・ケースをリダイレクトとして定義するかどうかを決定するには、次の要因を考慮してください。
リダイレクト・レンダリングを使用しない場合、ユーザーがページにブックマークを付けると、そのブックマークには現在ページのURLが含まれず、かわりに前ページのアドレスが含まれます。
ユーザーがページをリロードする場合に、URLを新しいビューにリフレッシュしないと、問題が発生する可能性があります。たとえば、ページでオーダーを送信する場合、ページのリロードによって同じオーダーが再送信される可能性があります。URLを新しいビューにリフレッシュしないために問題が発生する可能性がある場合は、redirect
要素を使用してナビゲーション・ケースを定義します。
例16-6 リダイレクト・レンダリングを指定して定義されたナビゲーション・ルール
<navigation-rule> <from-view-id>*</from-view-id> <navigation-case> <from-outcome>GlobalHome</from-outcome> <to-view-id>/app/SRList.jspx</to-view-id> <redirect/> </navigation-case> ... <navigation-case> <from-outcome>GlobalLogout</from-outcome> <to-view-id>/app/SRLogout.jspx</to-view-id> <redirect/> </navigation-case> <navigation-case> <from-outcome>dialog:GlobalContact</from-outcome> <to-view-id>/app/SRContact.jspx</to-view-id> </navigation-case> </navigation-rule>
Sun JSFの参照実装では、faces-config.xml
ファイルのナビゲーション・ルールを読み取り、NavigationHandler
クラスをコールして、ナビゲーション・ルールを評価して表示するページを決定します。ナビゲーション・ルールの評価方法を理解しておくと、ナビゲーションの問題をデバッグする際に役立ちます。
実行するナビゲーション・ルールを評価する際に、ナビゲーション・ハンドラは次の3つのものを調査します。
現在ページのID
リンクの処理に使用されるアクション・メソッド
action
属性の結果文字列値、またはアクション・メソッドによって戻される文字列
ナビゲーション・ハンドラは、次の方法で、ナビゲーションの結果およびルールを評価します。
アクション・メソッドによって戻された結果がnull
の場合、そのまま戻って現在ページを再表示します。
すべてのナビゲーション・ルールを同じfrom-view-id
値でマージします。
from-view-id
値がビューIDと完全に一致するルールが存在する場合は、そのルールを使用します。
すべてのパターンベース・ナビゲーション・ルールを評価し、接頭辞(ワイルドカード文字より前の部分)が現在ビューのIDの対応する接頭辞と一致するかどうかを判断します。
一致するルールが存在する場合は、一致する接頭辞が最も長いルールを使用します。from-view-id
要素がないルールが存在する場合は、そのルールを使用します。
一致するものがまったくない場合は、現在ページを再表示します。
ナビゲーション・ハンドラはナビゲーション・ルールを一致するfrom-view-id
値でマージするため、選択元となるナビゲーション・ケースが複数存在する場合があります。適切なナビゲーション・ルールを決定すると、ナビゲーション・ハンドラは優先順位が付けられた一連の条件に基づいて使用するケースを評価します。ある条件を満たすケースがない場合は、ケースが見つかるか、すべての条件が評価されてしまうまで、その次の条件が適用されます。ケース評価条件は次のとおりです(優先順位の高い順に示します)。
ケースのfrom-outcome
とfrom-action
の両方の値が現在のアクション・メソッドとaction
値と一致する場合は、そのケースを使用します。
ケースにfrom-action
要素がなく、from-outcome
値が現在のaction
値と一致する場合は、そのケースを使用します。
ケースにfrom-outcome
要素がなく、from-action
値が現在のアクション・メソッドと一致する場合は、そのケースを使用します。
from-outcome
要素もfrom-action
要素もないケースがある場合は、そのケースを使用します。
いずれの条件も満たすケースがない場合は、現在ページを再表示します。
ヒント: ページのUIコンポーネントでOracle ADFバインディングを使用する場合、行セットのイテレータが現在行を追跡します。ユーザーがページのナビゲーション・ボタンを使用するかわりにブラウザの「戻る」ボタンをクリックすると、イテレータが無視されるので、イテレータと表示されるページとの同期がずれてしまいます。ユーザーがブラウザの「戻る」ボタンをクリックしたときに発生する処理の詳細は、13.4.4項「ブラウザの「戻る」ボタンについての考慮事項」を参照してください。 |
すでに説明した基本ナビゲーション・ルールに加えて、ナビゲーション・ルールを複数のJSF構成ファイルに定義する、あるいはオーバーラップするルールを定義することができます。また、オーバーラップするナビゲーション・ケースおよび異なるルール間で分割されるケースを定義することもできます。
大規模なアプリケーションでは、アプリケーションの特定領域内のページに対するナビゲーション・ルールを個別のJSF構成ファイルに定義する場合があります。しかし、アプリケーションのどのページにも適用されるルールを任意のJSF構成ファイルに指定することができます。特に、各JSF構成ファイルでは、いくつかの一般的なナビゲーション機能(ホームページへ戻る、ヘルプ情報を表示するなど)に対するルールを定義できます。このような場合、ナビゲーション・イベントが実行時に発生すると、すべてのJSF構成ファイルのルールは同時に考慮されます。JDeveloperには、個々のJSF構成ファイルごとに1つのナビゲーション・モデラー・ダイアグラムがあります。
アプリケーションで複数のJSF構成ファイルを使用する場合、JSFはアプリケーションの構成設定を事前に定義された順に検出およびロードします。(構成設定の評価方法の説明は、第11章「ADF Facesの概説」を参照してください。)
グローバル・ルールまたはパターンベース・ルールを利用して、オーバーラップするルールの階層を定義できます。
ルールの階層を定義すると、特定のナビゲーション・ケースは特定のページに送られ、一般的なケース(「ホーム」ボタンまたは「ヘルプ」ボタンのクリックなど)はアプリケーション全体で同じ方法で処理されるようになります。
たとえば、次のようにfrom-view-id
値を定義して、ルールの階層を作成できます。
/products/select.jsp
: 1ページにのみルールを適用します。
/product/*
: 最初のルールの対象となるページを含め、productディレクトリ内のすべてのページにルールを適用します。
/*
: 前の2つのルールの対象となるページを含め、すべてのページに適用します。
オーバーラップするルールは、単一のルールまたは複数のルールに定義できます。ユーザーがリンクをクリックすると、より特定的なケースから先に考慮され、次により一般的なケースが考慮されます。
同じページに対して複数のナビゲーション・ルールを定義できるため、相互に競合するルールを定義する可能性があります。また、複数のJSF構成ファイルにナビゲーション・ルールを定義できるため、似たようなルールが異なるファイルに定義される場合もあります。例16-7に、同じ構成ファイルにおける競合するルールの例を示します。
2つ以上のケースに同じfrom-view-id
、from-action
およびfrom-outcome
の値が存在するといった競合がある場合は、最後のケース(faces-config.xml
で記述される順序で)が使用されます。異なる構成ファイルに定義されたルール間で競合がある場合は、最後にロードされる構成ファイルのルールが使用されます。構成ファイルは、web.xml
ファイルに記述される順序でロードされます。
例16-7 競合するナビゲーション・ケース
<navigation-rule> <from-view-id>*</from-view-id> <navigation-case> <from-outcome>globalhelp</from-outcome> <to-view-id>/menu/generalHelp.html</to-view-id> <redirect/> </navigation-case> </navigation-rule> <navigation-rule> <from-view-id>*</from-view-id> <navigation-case> <from-outcome>globalhelp</from-outcome> <to-view-id>/menu/help.html</to-view-id> <redirect/> </navigation-case> </navigation-rule>
異なるナビゲーション・ルール間で、1つのページ上のリンクに対するナビゲーション・ケースを分割できます。たとえば、アプリケーションでアプリケーションの特定の部分にナビゲートするための一連の共通コントロールをユーザーに示す場合、あるルールではすべての共通コントロールに対するナビゲーション・ケースを定義する一方で、別のナビゲーション・ルールではその他のコントロールからのナビゲーションを定義することができます。
複数のルール間で分割されるナビゲーションを定義するには、例16-8に示すように、すべてのナビゲーション・ケースをひとまとめにして定義する別個のナビゲーション・ルールを作成する必要があります。これらのルールが評価されると、より特定的なナビゲーション・ケースから先に使用され、次により一般的なケースが使用されます。
例16-8 複数のルール間で分割されるナビゲーション・ケース
<navigation-rule> <from-view-id>/order.jsp</from-view-id> <navigation-case> <from-action>#{backing_home.submit}</from-action> <from-outcome>success</from-outcome> <to-view-id>/summary.jsp</to-view-id> </navigation-case> <navigation-case> <from-action>#{backing_home.check}</from-action> <from-outcome>success</from-outcome> <to-view-id>/check.jsp</to-view-id> </navigation-case></navigation-case> </navigation-rule> <navigation-rule> <from-view-id>/order.jsp</from-view-id> <to-view-id>/again.jsp</to-view-id> </navigation-case> </navigation-rule>
ナビゲーション・モデラーを使用してページ・ナビゲーションを作成およびメンテナンスする際に、次の特徴に注意してください。
XMLエディタを使用してfaces-config.xml
ファイルに直接加えられた、あるいは構成エディタで加えられたナビゲーション・ルールへの変更により、通常、ナビゲーション・モデラーはリフレッシュされます。各JSF構成ファイルには、独自のナビゲーション・モデラー・ダイアグラムが含まれます。ナビゲーション・ダイアグラムの情報がfaces-config.xml
ファイルの情報と一致しない場合は、ダイアグラムを右クリックして「ダイアグラム」→「faces-configからダイアグラムのリフレッシュ」の順に選択すると、ダイアグラムを手動でリフレッシュできます。
ダイアグラムでナビゲーション・ケースを削除すると、関連付けられたnavigation-case
要素はfaces-config.xml
ファイルから削除されます。ルールのケースをすべて削除すると、navigation-rule
要素はfaces-config.xml
ファイルに残ります。ルールは、faces-config.xml
ファイルで直接削除できます。
ダイアグラムでナビゲーション・ケースのラベルを編集すると、関連付けられたnavigation-case
要素はfaces-config.xml
ファイルで更新されます。ダイアグラムでは、ナビゲーション・ケースの宛先を変更できません。しかし、JSF構成エディタでまたはfaces-config.xml
ファイル自体で直接、ナビゲーション・ケースの宛先を変更することができます。
ページ・アイコンをナビゲーション・ダイアグラムから削除しても、関連付けられたページ・ファイルはアプリケーション・ナビゲータのViewControllerプロジェクトのWeb Contentフォルダから削除されません。
ページを手動で編集しても、ナビゲーション・ダイアグラムまたは関連付けられたfaces-config.xml
は自動的に更新されません。逆に、既存のページの動作に影響する変更をページ・フローに加えても、ページのコードは自動的に更新されません。ナビゲーション・ダイアグラムとWebページの変更を整合させるには、ナビゲーション・ダイアグラムでページを右クリックし、「ダイアグラム」→「すべてのページからダイアグラムをリフレッシュ」の順に選択します。
ナビゲーション・モデラー・ダイアグラムは、faces-config.xml
ファイルのデフォルトのエディタです。大規模なアプリケーションまたは複雑なアプリケーションがある場合は、ファイル・サイズが大きいためにダイアグラムのロードが遅い場合があります。JSF構成ファイルに対してJSFダイアグラム・ファイルを作成しない場合は、「ツール」→「設定」→「ファイル・タイプ」→「デフォルトのエディタ」→「JSF構成ファイル」オプションの順に選択して、デフォルトのエディタを変更します。faces-config.xml
ファイルを初めて開く前にデフォルトのエディタを変更すると、明確に要求しないかぎり、ダイアグラム・ファイルは作成されません。
コンポーネントが静的ナビゲーションを使用して定義されている場合、action
属性の結果値は、常に同じナビゲーション・ケースをトリガーする定数値です。ユーザーが静的ナビゲーションを使用しているコンポーネントをクリックすると、特定のJSFページが表示されます。代替ナビゲーション・パスはありません。
静的ナビゲーションを使用するには、from-action
値ではなく、from-outcome
値を使用してナビゲーション・ケースを作成します。ナビゲーション・ボタンまたはリンクのaction
属性に、ナビゲーション・ケースのfrom-outcome
要素に入力した値と一致する定数の結果値を指定します。
たとえば、例16-9に示すように、Confirm
のfrom-outcome
値を指定してナビゲーション・ケースを作成した場合は、例16-10に示すように、action
属性の静的値としてConfirm
を指定するボタンまたはリンクをページ上に作成します。この場合、ユーザーがボタンをクリックすると、ナビゲーション・ケースによってConfirmAction
ページが表示されます。
例16-9 faces-config.xmlファイルに定義されたナビゲーション・ケース
<navigation-case> <from-outcome>Confirm</from-outcome> <to-view-id>/app/ConfirmAction.jspx</to-view-id> </navigation-case>
静的結果を使用するナビゲーション・コンポーネントを作成するには、コンポーネント・パレットまたはデータ・コントロール・パレットを使用します。データ・コントロール・パレットを使用すると、コンポーネントのactionListener
属性は、データ・コントロールの操作またはメソッドにバインドされます。コンポーネントを作成したら、action
属性に結果値を指定できます。ユーザーがコンポーネントをクリックすると、アプリケーションは結果値およびナビゲーション・ケースによって決定されたページにナビゲートします。しかし、コンポーネントがデータ・コントロールにバインドされている場合は、最初に操作またはメソッドが起動し、次にナビゲーションが実行されます。
データ・コントロール・メソッドにバインドされたコマンド・コンポーネントの詳細は、17.3項「メソッドを実行するためのコマンド・コンポーネントの作成」を参照してください。
静的結果を使用するナビゲーション・コンポーネントを作成する手順:
次のいずれかの方法で、ナビゲーション・コンポーネントを作成します。
コンポーネント・パレットのADF Faces Coreページから、CommandButton
コンポーネントまたはCommandLink
コンポーネントをページにドラッグします。
ヒント: JSFのcommandButton コンポーネントまたはcommandLink コンポーネントを使用することもできます。 |
データ・コントロール・パレットから、操作またはメソッドをページにドラッグ・アンド・ドロップし、ポップアップ・メニューの「ADFコマンド・ボタン」または「ADFコマンド・リンク」を選択します。
パラメータを取得するメソッドをドラッグ・アンド・ドロップすると、ADFコマンド・ボタンおよびコマンド・リンク・コンポーネントは、ポップアップ・メニューの「メソッド」の下に表示されます。「アクション・バインディング・エディタ」が表示され、メソッドに渡すパラメータ値を定義できます。パラメータをメソッドへ渡す方法の詳細は、17.4項「コマンド・コンポーネントを使用したパラメータ値の設定」を参照してください。
構造ウィンドウで、ナビゲーション・コンポーネントを選択し、プロパティ・インスペクタを開きます。
ヒント: プロパティ・インスペクタを開くためのショートカットは、[Ctrl]+[Shift]+[I]です。 |
プロパティ・インスペクタに表示される「Action」フィールドに、結果値を入力します。
値は、定数にするか、または文字列に評価されるEL式にする必要があります。ページのナビゲーション・ケースにすでに定義されている結果のリストを表示するには、プロパティ・インスペクタで「Action」フィールドのドロップダウンをクリックします。
ヒント: 特定のナビゲーション・ケースをトリガーする場合は、action 属性に入力する結果値がそのナビゲーション・ケースの結果値と大/小文字も含めて完全に一致する必要があります。アクションによって指定される結果がナビゲーション・ケースのどの結果とも一致しない場合、ナビゲーションはデフォルトのナビゲーション・ルール(存在する場合)によって処理されるか、ナビゲーションは発生しません。
また、 |
静的結果値を指定してナビゲーション・コンポーネントを作成すると、そのコンポーネントはJSFページに追加されます。初めて行う場合は、コンポーネントに指定されたナビゲーションの結果を処理するナビゲーション・ケースをfaces-config.xml
ファイルに追加する必要があります。
例16-11に、コンポーネント・パレットから使用できるADF FacesのcommandLink
コンポーネントを使用して作成された単純なナビゲーション・コンポーネントを示します。このコマンド・リンクは、SRDemoアプリケーションの多くのページに表示され、アプリケーション情報を表示するSRAboutページにナビゲートします。
ナビゲーション・パスが1つしかないため、このコマンド・リンクはaction
属性の静的結果を使用して定義されています。結果値はGlobalAbout
で、例16-12に示すナビゲーション・ケースのfrom-outcome
値と一致します。ナビゲーション・ケースは、アプリケーション内のすべてのページに適用されるグローバル・ナビゲーション・ルールに属しています。
例16-11 静的結果値を指定するナビゲーション・コンポーネント
<af:commandLink text="#{res['srdemo.about']}" action="GlobalAbout" immediate="true"/>
静的結果値をナビゲーション・コンポーネントに明示的に指定するかわりに、ナビゲーション・コンポーネントのaction
属性をアクション・メソッドにバインドして結果を動的に決定できます。アクション・メソッドとは、バッキングBean(マネージドBeanとも呼ぶ)内のメソッドで、アクション(ユーザー入力を保存するなど)を実行して結果値を戻すことができます。結果値により、メソッドがアクションを実行した後に表示される次のページが決定されます。たとえば、ページのユーザー入力を検証するアクション・メソッドは、入力が有効な場合はある結果を、入力が無効な場合は別の結果を戻します。これらの異なる結果はそれぞれ別個のナビゲーション・ケースをトリガーし、アプリケーションは2つのターゲット・ページのいずれかにナビゲートします。静的結果と同様、動的結果は一致するfrom-outcome
値が含まれるナビゲーション・ケースまたはデフォルトのナビゲーション・ケースをトリガーします。
ナビゲーション・コンポーネントにバインドされるメソッドは、パラメータがないパブリック・メソッドであり、アクションの結果を表す文字列を戻す必要があります。アクション・メソッドは、実行する処理に応じて複数の結果のいずれかを戻すことができます。すなわち、メソッドのロジックに条件付きの結果を定義できます。メソッドによって戻される結果は、(どのナビゲーション・ケースにも指定されていないすべての結果を処理するデフォルトのルールを使用しないかぎり)ページのナビゲーション・ルールのケースのいずれかに定義する必要があります。
ヒント: ADFアプリケーションでは、ほとんどのデータ・オブジェクトの処理は、データ・コントロールによって処理されます。そのため、動的結果を使用するナビゲーション・コンポーネントがデータ・オブジェクトに対してなんらかの処理(作成、編集、削除など)を実行する必要がある場合、ADFバインディング・コンテナをインジェクトするバッキングBeanのメソッドにそのコンポーネントをバインドする必要があります。バッキングBeanがADFバインディング・コンテナをインジェクトすると、指定されたデータ・コントロールのメソッドをコールしてデータの処理を実行し、その結果に基づいてナビゲーションの結果をUIコンポーネントに戻します。バッキングBeanへのバインディング・コンテナのインジェクトの詳細は、17.5項「宣言メソッドのオーバーライド」を参照してください。 |
ナビゲーション・コンポーネントの結果を動的に決定する場合、コンポーネントをバッキングBeanのメソッドにバインドできます。バッキングBeanは、なんらかのアプリケーション・ロジックを実行し、その結果に基づいて結果を戻します。戻された結果により、実行されるナビゲーション・ルールが決定されます。バッキングBeanの作成の詳細は、11.5項「Webページ用のバッキングBeanの作成および使用」を参照してください。
バッキングBeanにバインドするナビゲーション・コンポーネントを作成する手順:
コンポーネント・パレットのADF Faces Coreページから、CommandButton
またはCommandLink
をページにドラッグします。
ヒント: JSFのcommandButton コンポーネントとcommandLink コンポーネントを使用することもできます。 |
ビジュアル・エディタで、UIコンポーネントをダブルクリックし、図16-5に示す「バインドActionプロパティ」ダイアログを表示します。
「バインドActionプロパティ」ダイアログでは、バッキングBeanとコンポーネントのバインド先とするメソッドを指定できます。ページの作成時に自動バインディングを有効にした場合は、「バインドActionプロパティ」ダイアログに静的結果を指定するためのオプションは表示されません。
「バインドActionプロパティ」ダイアログで、次のいずれかの方法で、バッキングBeanとコンポーネントのバインド先とするメソッドを指定します。
「新規」をクリックして、新しいバッキングBeanを作成します。「マネージドBeanの作成」ダイアログが表示されます。このダイアログを使用して、Beanおよびクラスに名前を付けます。
既存のバッキングBeanおよびメソッドをドロップダウン・リストから選択します。
バッキングBeanとメソッドを指定した後、「バインドActionプロパティ」ダイアログで「OK」をクリックします。
JDeveloperにソース・エディタが表示されます。新規のメソッドの場合は、例16-13に示すようなスタブ・メソッドがソース・エディタに表示されます。既存のメソッドの場合は、スタブ・メソッドではなくそのメソッドがソース・エディタに表示されます。
必要な処理ロジックをメソッドに追加します。
メソッドの戻り値を適切な結果文字列に変更します。
特定の条件に基づいて複数の結果のいずれかを戻す条件付きロジックを記述できます。たとえば、処理中にエラーが発生した場合にはnull
を、処理が正常終了した場合は別の結果値を戻すことができます。null
の戻り値により、ナビゲーション・ハンドラはナビゲーション・ケースを評価せずに、そのまま現在ページを再表示します。
ヒント: 特定のナビゲーション・ケースをトリガーするには、action 属性に入力する結果値がそのナビゲーション・ルールの結果値と大/小文字も含めて完全に一致する必要があります。 |
動的結果を指定するナビゲーション・コンポーネントを作成すると、コンポーネント・タグのaction
属性にEL式が追加されます。このEL式は、なんらかのアプリケーション処理(ユーザー入力の保存など)を実行し、結果値を戻すバッキングBeanのメソッドを参照します。
例16-14に、動的結果値を使用する、SRDemoアプリケーションのSRCreateConfirmページ上のボタンを示します。このボタンは、データ・コントロール・パレットのポップアップ・メニューから使用できるADF FacesのcommandButton
コンポーネントを使用して作成されています。ユーザーがこのボタンをクリックすると、サービス・リクエストが新規作成されます。
例16-14 動的結果を使用するナビゲーション・コンポーネント
<af:commandButton text="#{res['srcreate.submit.button']}" partialSubmit="false" action="#{backing_SRCreateConfirm.createSRButton_action}" id="createSRButton"/>
このボタンのaction
属性は、例16-15に示すSRCreateConfirm
バッキングBeanのcreateSRButton_action
メソッドにバインドされています。
例16-15 動的結果を戻すバッキングBeanのメソッド
public String createSRButton_action() { BindingContainer bindings = getBindings(); OperationBinding operBinding = bindings.getOperationBinding("createServiceRequest"); Integer newServiceRequestId = (Integer)operBinding.execute(); //Put the number of the created service ID onto the request as an // example of passing data in that way JSFUtils.setRequestAttribute("SRDEMO_CREATED_SVRID",newServiceRequestId); return "Complete"; }
バッキングBeanのメソッドはサービス・リクエストを作成し、結果値のComplete
を戻します。サービス・リクエストを作成するために、バッキングBeanのメソッドは、最初にボタンを作成するために使用された宣言メソッドcreateServiceRequest
をオーバーライドします。あるメソッドが宣言メソッドをオーバーライドすると、JSFランタイムにより、bindings
と呼ばれる管理プロパティを使用して現在のページのバインディング・コンテナがインジェクトされます。バッキングBeanのメソッドは、getBindings()
プロパティgetterをコールします。このメソッドは現在のバインディング・コンテナにアクセスし、SRService
データ・コントロールのcreateServiceRequest
メソッドに対してメソッド・アクション・バインディングを実行します。宣言メソッドのオーバーライドの詳細は、17.5項「宣言メソッドのオーバーライド」を参照してください。
例16-16に、バッキングBeanによって戻される結果を処理するナビゲーション・ルールを示します。
ユーザーが動的結果を保持するナビゲーション・コンポーネントをクリックすると、バッキングBeanのアクション・メソッドが実行されます。メソッドは、通常、なんらかのユーザー入力を処理し、結果値をページに戻します。JSFナビゲーション・ハンドラはアクション・メソッドによって戻された結果を評価し、from-outcome
要素に同じ値が定義されているナビゲーション・ケースに適合させます。一致するルールが実行され、ルールのto-view-id
要素に定義されたページが表示されます。メソッドが結果を戻さない場合、または結果がどのナビゲーション・ケースとも一致しない場合は、ユーザーは現在ページから移動しません。
アクション・メソッドを使用してアプリケーションでナビゲーションを処理する場合、メソッドを起動するアクション・リスナー・インタフェースを実装する必要はありません。これは、JSFではデフォルトのアクション・リスナーを使用してページ・ナビゲーションのアクション・メソッドを起動するためです。メソッドの論理的な結果値は、レスポンスのレンダリングに使用するページをJSFナビゲーション・ハンドラに指示するために使用されます。
アクション・メソッドが処理ロジックに基づいて異なる結果を戻す場合、デフォルトのナビゲーション・ケースを定義して、特定のナビゲーション・ケースでは処理されない結果をメソッドが戻さないようにすることができます。
デフォルトのナビゲーション・ケースは、特に他のナビゲーション・ケースで処理されない結果すべてを受け取ります。デフォルトのナビゲーション・ケースを定義するには、別のケースで処理されない結果にそのケースを適用するようにナビゲーション・ハンドラに指示するfrom-outcome
要素を除外します。
たとえば、アクション・メソッドを使用して「発行」コマンド・ボタンを処理するとします。成功のケースは、その結果に対する特定のページを表示して処理できます。その他すべての結果の場合には、処理を続行できないことを説明するページを表示できます。例16-17に、この例のナビゲーション・ケースを示します。
例16-17 デフォルトのナビゲーション・ケースを指定したナビゲーション・ルール
<navigation-rule> <from-view-id>/order.jsp</from-view-id> <navigation-case> <from-action>#{backing_home.submit}</from-action> <from-outcome>success</from-outcome> <to-view-id>/summary.jsp</to-view-id> </navigation-case> <navigation-case> <from-action>#{backing_home.submit}</from-action> <to-view-id>/again.jsp</to-view-id> </navigation-case> </navigation-rule>
この例では、最初のナビゲーション・ケースは動的ナビゲーション・ケースで、アクション・メソッドが結果を決定しています。結果がsuccess
の場合、ユーザーは/summary.jsp
ページにナビゲートします。
2つ目のナビゲーション・ケースはデフォルトのナビゲーション・ケースで、アクション・メソッドによって戻されるその他すべての結果を受け取り、すべての結果に対して/again.jsp
を表示します。デフォルトのケースでfrom-outcome
値が指定されていないことに注意してください。これにより、アクション・メソッドによって戻された結果が他のどのケースとも一致しない場合は、このケースが実行されます。
ユーザー・インタフェースに関する情報を必要とするアクションがある場合、アクション・リスナー・メソッドをナビゲーション・コンポーネントで使用できます。カリフォルニア州のイメージを使用するボタンがあり、ユーザーが国を選択してその国に関する情報を表示できるようにするとします。国ごとの結果を格納して選択された国を特定するアクション・リスナー・メソッドと、結果値を使用して正しい国のページにナビゲートするアクション・メソッドを実装できます。
アクション・メソッドとアクション・リスナー・メソッドをコンポーネントで使用するには、例16-18に示すようにそれらのメソッドを参照します。
action
属性をバッキングBeanにバインドするかわりに、ナビゲーション結果を戻すデータ・コントロール・メソッドにこの属性をバインドできます。action
属性をデータ・コントロール・メソッドにバインドするには、例16-19に示すように、ADFバインディング式を手動で入力し、outcome
バインディング・プロパティを使用する必要があります。
例16-19 データ・コントロール・メソッドにバインドされたナビゲーション・コンポーネント
<af:commandButton text="Delete Service History Notes" action="#{bindings.deleteServiceHistoryNotes.outcome}"/>
outcome
プロパティは、FacesCtrlActionBinding
クラスのoutcome()
メソッドを起動します。これにより、同じクラスのexecute
メソッドがコールされ、データ・コントロール・メソッドが実行されます。データ・コントロール・メソッドによって値が戻されると、その値はoutcome()
メソッドにより(必要に応じて)文字列に変換され、action
属性に戻されます。