この章の内容は次のとおりです。
JavaServer Facesアプリケーションのライフサイクルは、クライアントがページに対するHTTPリクエストを行ったときに始まり、サーバーがHTMLに変換されたページで応答すると終了します。ページ・リクエスト時のJSFライフサイクルとADF Facesライフサイクルの各フェーズと、各フェーズの前後にイベントがどのように処理されるかについて説明します。
ADF Facesアプリケーションでは、JSFライフサイクルとADF Facesライフサイクルの両方が使用されます。ただし、ADF FacesライフサイクルではJSFライフサイクルが拡張され、クライアント側の値のライフサイクル、1つのページに複数のフォームを使用する弊害(ユーザーの編集内容の消失など)なしに独立して送信可能なセクションをページに作成できるサブフォーム・コンポーネント、追加スコープなどの追加機能を提供します。
フレームワークによって提供されるライフサイクルの強化についてよりよく理解するには、標準のJSFライフサイクルについて理解することが重要です。この項の説明は概要にすぎません。詳細な説明は、http://www.jcp.org/en/jsr/detail?id=314
にあるJSFの仕様を参照してください。
JSFページが送信され、新しいページがリクエストされると、JSFページ・リクエスト・ライフサイクルが起動されます。このライフサイクルでは、ページの値の送信、現在のページのコンポーネントの検証、コンポーネントのナビゲーションと結果ページへの表示および状態の保存とリストアが処理されます。FacesServlet
オブジェクトで、JSFアプリケーションのページ・リクエスト・ライフサイクルが管理されます。FacesServlet
オブジェクトで、リクエスト処理に必要な情報を含み、ライフサイクルを実行するオブジェクトを起動するFacesContext
と呼ばれるオブジェクトが作成されます。
JSFライフサイクル・フェーズでは、UIコンポーネント・ツリーを使用してfacesコンポーネントの表示を管理します。このツリーはJSFページのランタイム表現で、ページ内の各UIコンポーネント・タグがツリーのUIコンポーネント・インスタンスに対応します。
図5-1に、ページ・リクエストのJSFライフサイクルを示します。ここに示すとおり、各フェーズの前後でイベントが処理されます。
JSFアプリケーションでは、ページ・リクエスト・ライフサイクルは次のようになります。
ビューのリストア:コンポーネント・ツリーが構築されます。これが初めてのレンダリングでない場合(ページがサーバーに送り返された場合)、適切な状態でツリーがリストアされます。これが初めてのレンダリングの場合、コンポーネント・ツリーが作成され、レスポンスのレンダリング・フェーズに移ります。
リクエスト値の適用: ツリーの各コンポーネントでリクエスト・パラメータから新規の値が(decodeメソッドを使用して)抽出され、ローカルに格納されます。関連付けられているほとんどのイベントは、後の処理のためにキューされます。コンポーネントのimmediate
属性がtrue
に設定されている場合、検証、変換およびコンポーネントに関連付けられているイベントがこのフェーズで処理されます。「immediate属性の使用」を参照してください。
検証の処理: コンポーネントのローカル値が、入力タイプから基礎のデータ型に変換されます。コンバータが失敗した場合、このフェーズが続行されて完了します(残りのすべてのコンバータ、バリデータおよび必要なチェックが実行されます)が、完了時にライフサイクルがレスポンスのレンダリング・フェーズに移ります。
失敗がない場合、コンポーネントのrequired
属性が確認されます。値がtrue
で、関連付けられているフィールドに値が含まれている場合、関連付けられているバリデータが実行されます。値がtrue
で、フィールド値がない場合、このフェーズは完了します(残りのすべてのバリデータが実行されます)が、ライフサイクルがレスポンスのレンダリング・フェーズに移ります。値がfalse
の場合、値が入力されていないかぎり(この場合は検証が実行されない)、フェーズが完了します。変換と検証の詳細は、「入力の検証および変換」を参照してください。
このフェーズの最後に、変換後のローカル値が設定され、検証および変換のエラー・メッセージとイベントがFacesContext
にキューイングされ、値変更イベントが配信されます。
ヒント
要約すると、編集可能な入力コンポーネントの検証の処理フェーズでの手順は次のとおりです。
コンバータが失敗した場合、必要なチェックとバリデータが実行されません。
コンバータは成功したが、必要なチェックが失敗した場合、バリデータが実行されません。
コンバータと必要なチェックが成功した場合、すべてのバリデータが実行されます。1つのバリデータが失敗した場合でも、残りのバリデータは実行されます。これは、ユーザーがエラーを修正する際に使用できる、入力されたデータの問題点を可能なかぎりフィードバックするためです。
たとえば、2015年の日付のみを受け入れるdateTimeRange
バリデータがあり、ユーザーが日曜日を選択できないdateRestrictionValidator
バリデータがあるとします。ユーザーがNovember 16, 2014
(日曜日)と入力した場合、両方のバリデータが失敗することをフィードバックし、ユーザーが有効な日付を入力する可能性を最大限にします。
モデル値の更新: 検証されたコンポーネントのローカル値がモデルに移動され、ローカル・コピーが破棄されます。
アプリケーションの起動: アプリケーション・レベルのロジック(イベント・ハンドラなど)が実行されます。
レスポンスのレンダリング: ツリー内のコンポーネントがレンダリングされます。後続のリクエストおよびビューのリストア・フェーズ用に状態情報が保存されます。
ライフサイクルの説明の一環として、ユーザーが日付を入力し、ボタンをクリックして入力値を送信する単純な入力テキスト・コンポーネントを持つページを考えてみます。valueChangeListener
メソッドもコンポーネントに登録されています。次に、例のコードを示します。
<af:form> <af:inputText value="#{mybean.date}" valueChangeListener="#{mybean.valueChangeListener}"> <af:convertDateTime dateStyle="long"/> </af:inputText> <af:button text="Save" actionListener="#{mybean.actionListener}"/> </af:form>
ユーザーが文字列「June 25, 2015」を入力し、送信ボタンをクリックするとします。図5-2に、値がライフサイクルでどのように受け渡され、各イベントがどの時点で処理されるかを示します。
ADF FacesライフサイクルまたはJSFライフサイクルで、コンポーネントのimmediate属性がtrueに設定されている場合、そのコンポーネントに関連付けられている検証、変換、イベントは、後のフェーズではなくリクエスト値の適用フェーズに処理されます。現在の画面で入力フィールドにあるデータを処理せずに他のページに移動するには、この属性を使用します。
immediate
属性を使用して、ライフサイクルのリクエスト値の適用フェーズまでコンポーネントの処理を進めることができます。actionSource
コンポーネント(commandButton
など)がimmediate
に設定されている場合、イベントはアプリケーションの起動フェーズではなくリクエスト値の適用フェーズで配信されます。actionListener
ハンドラでレスポンスのレンダリング・フェーズがコールされ、検証およびモデルの更新フェーズが省略されます。
たとえば、「取消」ボタンをimmediate
に構成し、アクションが前のページに戻るために使用される文字列を返すようにする場合があります(ナビゲーションの詳細は、「ナビゲーション・コンポーネントの使用」を参照してください)。「取消」ボタンはimmediate
に設定されているため、ユーザーが「取消」ボタンをクリックすると、図5-3に示すように、すべての検証がスキップされ、入力されたデータはモデルに更新されず、ユーザーは期待どおりにナビゲートします。
注意:
ナビゲーションを提供せず、immediate
に設定されているボタンは、レスポンスのレンダリング・フェーズに直接進み、検証、モデルの更新、アプリケーションの起動のフェーズは省略され、新しい値はサーバーにプッシュされません。
コマンド・コンポーネントと同様に、表示イベントを呼び出すコンポーネント(showDetail
コンポーネントなど)、およびeditableValueHolder
コンポーネント(inputTextコンポーネントなど、変更可能な値を保持するコンポーネント)では、immediate
に設定されている場合、イベントはリクエスト値の適用フェーズで配信されます。一方、editableValueHolderコンポーネントでは、フェーズをスキップするかわりに、immediateコンポーネントのvalueChangeEvents
イベントの変換、検証および配信が、検証の処理フェーズではなく、ライフサイクル初期のリクエスト値の適用フェーズで実行されます。スキップされるライフサイクル・フェーズはありません。
図5-4に、immediate属性がtrueに設定されている入力コンポーネントのライフサイクルを示します。入力コンポーネントは文字列として入力された日付を取得し、コマンド・ボタンがクリックされたときにDateオブジェクトとしてその日付を格納します。
入力コンポーネントのimmediate
属性をtrue
を設定すると、1つ以上の入力コンポーネントをその他のコンポーネントより前に検証する必要がある場合に役立ちます。これらのコンポーネントの1つで無効なデータが検出されると、同じページの他の入力コンポーネントの検証が省略されるため、ページに表示されるエラー・メッセージの数が削減されます。
たとえば、名前と住所の情報を収集するために使用するフォームがあり、そのNameフィールドをrequiredに設定したとします。住所のフィールドは、「国」ドロップダウン・フィールドで選択された国に基づいて変更する必要があります。ユーザーが国を選択するときに、名前のフィールドが空白でも検証エラーが発生しないように、ドロップダウン・フィールド(selectOneChoice
コンポーネントを使用して表示される)をimmediateに設定します。次の例に、住所フィールドのコードを示します(国の切替え機能は示していません)
<af:form id="f1"> <af:panelFormLayout id="pfl1"> <af:panelGroupLayout id="pgl2" layout="vertical"> <af:inputText label="Name" id="it1" value="#{bean.name}" required="true"/> <af:inputText label="Street" id="it2" value="#{bean.street}"/> <af:panelGroupLayout id="pgl1" layout="horizontal"> <af:inputText label="City" id="it3" value="#{bean.city}"/> <af:inputText label="State" id="it4" value="#{bean.state}"/> <af:inputText label="Zip" id="it5" value="#{bean.zip}"/> </af:panelGroupLayout> <af:selectOneChoice label="Country" id="soc1" immediate="true"> valueChangeListener="bean.countryChanged"> <af:selectItem label="US" value="US" id="si1"/> <af:selectItem label="Canada" value="Canada" id="si2"/> </af:selectOneChoice> </af:panelGroupLayout> </af:panelFormLayout> </af:form>
この例では、selectOneChoice
の値の変更イベントはリクエスト値の適用フェーズの後で起動されるため、countryChanged
リスナー・メソッドは名前のinputText
コンポーネントが検証される前に実行されます。しかし、編集可能なコンポーネントに対し、フェーズはスキップされないことに注意してください - この場合も検証はこのリクエスト中に実行されます。他のコンポーネントの検証を防ぐには、renderResponse
メソッドをリスナー・メソッドから直接呼び出す必要があります。この呼出しは、検証を含めたライフサイクルの残りの部分をスキップし、レスポンスのレンダリング・フェーズに直接ジャンプします。
public void countryChanged(ValueChangeEvent event) FacesContext context = Facescontext.getcurrentInstance(); . . . some code to change the locale of the form . . . context.renderresponse();
注意:
RenderResponse()
を呼び出すときは注意してください。部分的にライフサイクルを通過したコンポーネントは、トラブルの原因となる不完全な状態になることがあります。これらのコンポーネントの値は未検証でデコードされてモデルにプッシュされるため、RenderResponse().を呼び出すときに送信済の値をクリアする必要があります。 注意:
ページをそのまま残すことが必要で、immediateコンポーネント以外の値は送信しない場合にのみ、immediate
属性を使用します。取消の例では、そのページで値が送信されることはありません。住所の例では、他の値を何も送信せずにページを再レンダリングします。
immediate
属性によりコンポーネントはデコードされます(したがって、送信される値を持ちます)が、それ以上は処理されません。immediateアクションのコンポーネントの場合、他のコンポーネントが検証やモデルの更新フェーズに到達することはなく、送信された値はローカルの値に変換され、そのローカルの値がモデルにプッシュされ、クリアされます。このため、値は使用可能にはなりません。
他のフィールドの前に処理すべき多数のフィールドがある場合は、immediate
属性は使用しないでください。そのような場合は、ライフサイクルが実行されるときにサブフォーム内のフィールドのみが処理されるように、ページを別々のサブフォームに分割するのが最善です。
immediate
属性をtrueに設定することでよりよいパフォーマンスが得られる場合があります。ナビゲーション・トレインを作成し、navigationPane
コンポーネント内にcommandNavigationItem
コンポーネントがある場合、immediate
属性をtrueに設定して、次のページへの移動時に、現在のページ(トレイン・ストップ)からのデータの処理を回避します。詳細は、「トレイン・モデルの作成方法」を参照してください。他の値の前に入力コンポーネント値を検証する必要がある場合、immediate属性をtrue
に設定します。ライフサイクルの早い段階でエラーが検出され、その他の処理が行われずに済みます。
ADF Facesの部分ページ・レンダリング(PPR)では、JSFライフサイクルが最適化されます。イベント・ルート・コンポーネントを使用して、ページでの境界を決定すれば、その境界内のコンポーネントでのみライフサイクルを実行できます。
ADF Facesには、ページの特定のコンポーネントにのみJSFページ・リクエスト・ライフサイクル(変換と検証を含む)を実行する最適化されたライフサイクルが用意されています。この部分ページ・ライフサイクルは、部分ページ・レンダリング(PPR)と呼ばれます。特定のADF Facesコンポーネントはイベント・ルート・コンポーネントとして見なされ、最適化されたライフサイクルが実行される境界を決定します。イベント・ルート・コンポーネントは、2通りの方法で決定されます。1つは、特定のコンポーネントが常にイベント・ルートと見なされます。たとえば、panelCollection
コンポーネントはイベント・ルート・コンポーネントです。これは表の周囲にあり、特にツールバーを表示します。ツールバー上のボタンからトリガーされたアクション・イベントによって、ライフサイクルがpanelCollection
の子コンポーネントでのみ実行されます。
イベント・ルート・コンポーネントが決定されるもう1つの方法は、特定のイベントがイベント・ルートを指定する方法です。たとえば、showDetail
コンポーネントを展開または縮小する(「コンテンツの動的な表示および非表示」を参照)と送信される表示イベントは、showDetail
コンポーネントがルートであることを示すため、ライフサイクルはshowDetail
コンポーネントと任意の子コンポーネントでのみ実行されます。イベント・ルート・コンポーネントのリストを含め、PPRおよびイベント・ルートの詳細は、「イベントおよび部分ページ・レンダリング」を参照してください。
イベント・ルートで実行されているコンポーネントおよびその子コンポーネントとは別に、イベント・ルート階層外部の他のコンポーネントを最適化されたライフサイクルに参加するように宣言して構成できます。コンポーネントの特定のイベントに限って最適化されたライフサイクルをトリガーさせたり、実際に実行されるコンポーネントと単にリフレッシュされるだけのコンポーネントを設定することもできます。
ADF FacesフレームワークでのPPRの使用方法とアプリケーションでのPPRの使用方法の詳細は、「部分ページ・コンテンツの再レンダリング」を参照してください。
ADF Facesフレームワークは、クライアント側変換および検証を提供します。サーバーにアクセスせずにページで実行できる独自のJavaScriptベースのコンバータおよびバリデータを作成できます。
クライアント側検証を使用して、特定のクライアント・イベントがキューに入れられたときに、適切なフォームまたはサブフォームのクライアント検証をトリガーできます(サブフォームの詳細は、「サブフォームを使用したページでのセクションの作成」を参照してください)。このクライアント検証が失敗し、既知のエラーがあることがわかった場合は、通常サーバーに伝播するイベント(たとえば、フォームが送信されたときのボタンのactionEvent
)はサーバーに移動しません。イベントが配信されないということは、なにも送信されないということでもあり、クライアント・リスナーはコールされません。これは、サーバーで検証が失敗した場合にライフサイクルがレスポンスのレンダリング・フェーズにジャンプするサーバー側検証に似ています。アクション・イベントはキューに入れられますが、決して配信されず、actionListener
ハンドラ・メソッドは決してコールされません。
たとえば、ADF Facesで入力コンポーネントにrequired
属性を用意し、この検証がクライアントで実行されるとします。この属性をtrue
に設定すると、コンポーネントの値がnull
の場合、フレームワークでページにエラーが表示され、サーバーへの送信は必要ありません。次の例に、inputText
コンポーネントのrequired
属性をtrue
に設定し、actionListener
属性がマネージドBeanのメソッドにバインドされているボタンを含むコードを示します。
<af:form> <af:inputText id="input1" required="true" value="a"/> <af:button text="Search" actionListener="#{demoForm.search}"/> </af:form>
このページを実行した場合、inputText
コンポーネントの値のフィールドをクリアし、フィールドからタブ移動すると、フィールドが赤い縁取りで再表示されます。フィールドをクリックすると、図5-5に示すように、値が必要なことを示すエラー・メッセージが表示されます。サーバーへの送信はなく、エラーの検出とメッセージの生成はすべてクライアントで行われます。
図5-5クライアント側検証でサーバーへの送信なしにエラーを表示
この例で、値のフィールドをクリアし、「検索」ボタンをクリックした場合、必須フィールドが空でありエラーが発生するため、ページは送信されません。アクション・イベントは配信されず、アクション・リスナーにバインドされたメソッドは実行されません。サーバーで検証が失敗したことをクライアントが通知できる場合はページを送信する理由がないため、このプロセスは適切です。
クライアント側の検証と変換の詳細は、「入力の検証および変換」を参照してください。
ADF Facesには、form内で個別にコンポーネント値を送信できるサブリージョンを定義することで柔軟性を高めるサブフォーム・コンポーネントが用意されています。サブフォームのコンテンツは、特定の基準に基づいて検証できます。
JSF参照実装では、ページのセクションを別個に送信する場合、複数のフォームを使用する必要があります。ただし、複数のフォームにはページの状態の複数のコピーが必要なため、送信されないフォームでのユーザーの編集内容が失われる可能性があります。
ADF Facesには、別個に送信可能なページのセクションを示すサブフォーム・コンポーネントのサポートが追加されています。サブフォームのコンテンツは、サブフォーム内部のコンポーネントがページの送信に関与する場合にのみ検証(または処理)されるため、まったく別のフォーム要素を使用するという妥協をすることなく、検証されてモデルへプッシュされるコンポーネントのセットを比較的きめ細かく制御できます。サブフォームを使用するページの送信時に、ページの状態が一度だけ書き込まれ、すべてのユーザー編集内容が保持されます。
ベスト・プラクティス:
常にページごとに1つのみのform
タグを使用します。複数のform
タグを使用する必要がある場合は、subform
タグを使用します。
サブフォームでは、ページがそのサブフォーム外のコンポーネントによって送信された場合でも、リクエスト値の適用フェーズでその子コンポーネントを常に実行できます。ただし、検証の処理フェーズとモデル値の更新フェーズはスキップされます(これは、送信されない場合はリクエスト値の適用フェーズを実行できない通常のフォーム・コンポーネントとは異なります)。サブフォーム外のコンポーネントが送信アクションの原因となった場合にサブフォーム内のコンポーネントを検証の処理フェーズとモデル値の更新フェーズで処理できるようにするには、default
属性を使用します。サブフォームのdefault
属性をtrue
に設定すると、そのサブフォームはほとんどの点で他のサブフォームと同様に動作しますが、ページのどのサブフォームにもその子コンポーネントからの適切なイベントがない場合、default
がtrue
に設定されたサブフォームは、その子コンポーネントの1つが送信の原因となったかのように動作します。サブフォームの詳細は、「formの定義」を参照してください。
JSFアプリケーションで作成するオブジェクトは、指定されたスコープを定義するか、それがデフォルトになります。このオブジェクト・スコープによって、使用できる範囲と、アクセスできるユーザーが決まります。標準のJSFスコープも、JSFアプリケーションのオブジェクトに対して使用可能なADF Facesスコープを使用できます。
実行時、ページがデータにアクセスできるオブジェクト・スコープに必要なデータを格納することで、データをページに渡します。スコープによってオブジェクトの存続期間が決まります。オブジェクトをスコープに置くと、EL式を使用してスコープからアクセスできます。たとえば、foo
という名前のマネージドBeanを作成し、Beanをリクエスト・スコープに存続させるよう定義するとします。このBeanにアクセスするには、#{requestScope.foo}
という式を使用します。
標準JSFアプリケーションには、次の5種類のスコープがあります。
application
Scope
: オブジェクトは、アプリケーションの間使用できます。
session
Scope
: オブジェクトは、セッションの間使用できます。
viewScope
: オブジェクトは、ユーザーが現在のビューとの対話を終了するまで使用可能です。オブジェクトはUIViewRoot
オブジェクトのマップに格納されます。このオブジェクトは、ページがリフレッシュされるかビューにリダイレクトされると空になります。
ヒント
ページのリフレッシュまたは同じビューへのリダイレクト後もオブジェクトを残す必要がある場合は、ADF FacesバージョンのviewScope
を使用します。
flashScope: オブジェクトは、単一のビュー遷移中に使用可能で、次のビューに移動する前にクリアされます。flashScope
にパラメータ値を配置し、結果のページで使用可能にし、リダイレクト後も残すことができます。
request
Scope
: オブジェクトは、HTTPリクエストが送信されてから、レスポンスがクライアントに返るまでの間使用できます。
標準JSFスコープに加え、ADF Facesには次のスコープが用意されています。
pageFlow
Scope
: オブジェクトは、ユーザーがあるページから別のページへのナビゲートを続けるかぎり使用できます。ユーザーが新たなブラウザ・ウィンドウを開いてナビゲートを始めた場合、そのウィンドウで別のpageFlowScope
スコープを持ちます。
backingBean
Scope
: ページ・フラグメントと宣言コンポーネントのみに対するマネージドBeanに使用します。オブジェクトは、HTTPリクエストが送信されてから、レスポンスがクライアントに返るまでの間使用できます。このスコープは、複数のページ・フラグメントと宣言コンポーネントがページにある場合があり、値の競合を避けるために別々のスコープ・インスタンスに値を保持するために必要です。ページ・フラグメントまたは宣言コンポーネントに対して作成されるマネージドBeanには、backingBeanScope
スコープを使用します。
view
Scope
: オブジェクトは、現在のビューのIDが変更されるまで使用できます。viewScope
スコープを使用して特定のページの値を保持します。JSF viewScope
とは異なり、ADF FacesのviewScope
に格納されるオブジェクトは、ページのリフレッシュや同じビューIDへのリダイレクト後も残ります。
注意:
これらは標準JSFスコープではないため、EL式には、Beanを参照するためのスコープを明示的に含める必要があります。たとえば、pageFlowScope
スコープからMyBean
マネージドBeanを参照するには、#{pageFlowScope.MyBean}
という式になります。
オブジェクト・スコープは、プログラミング言語のグローバル変数およびローカル変数のスコープに相当します。スコープが広いほど、オブジェクトの可用性が高くなります。存続期間の間、これらのオブジェクトで特定のインタフェースの公開、情報の保持および他のオブジェクトへの変数とパラメータの受渡しを行うことができます。たとえば、sessionScope
スコープに定義されているマネージドBeanは、複数のページ・リクエストの間使用できます。しかし、requestScope
スコープに定義されているマネージドBeanは、1つのページ・リクエストの間のみ使用できます。
図5-6に、各タイプのスコープが有効な期間およびページ・フローとの関係を示します。
マネージドBeanを登録するスコープまたは値を格納するスコープを決める場合、可能なかぎり狭いスコープを常に使用するようにします。sessionScope
スコープは、ユーザー情報やコンテキスト情報などのセッション全体に関係する情報にのみ使用します。あるページから別のページへの値の受渡しには、sessionScope
スコープは使用しないようにします。
注意:
フルFusionテクノロジ・スタックを使用している場合、様々な構成ファイルにマネージドBeanを登録するためのオプションがあります。『Oracle Application Development FrameworkによるFusion Webアプリケーションの開発』のFusion WebアプリケーションでのマネージドBeanの使用に関する項を参照してください。
Oracle ADFには、実行時に作成される一時的な値の格納をサポートするpageFlowScope
Beanスコープが用意されています。様々な手順を用いて、アプリケーションでJavaコード内からpageFlowScope
にアクセスするか、Javaコードを記述せずにpageFlowScope
を使用することができます。
ADF FacesのpageFlowScope
スコープは、ページ間での値の受渡しを容易にするため、マスター/ディテール・ページを簡単に開発できます。pageFlowScope
スコープに追加された値は、redirect
ディレクティブを使用する場合でも、ユーザーがページ間を移動する際に自動的に継続使用できます。ただし、session
スコープとは異なり、これらの値を表示できるのは、現在のページ・フローまたはプロセス内のみです。ユーザーが新たなウィンドウを開いてナビゲートを始めた場合、そのウィンドウは固有のプロセスを持ちます。各ウィンドウに格納された値は独立したままです。
注意:
完全なFusionテクノロジ・スタックを使用していて、ADFバインド・タスク・フローのページ間またはADFリージョンとページの間での値の受渡しについての情報が必要な場合は、『Oracle Application Development FrameworkによるFusion Webアプリケーションの開発』の「ADFタスク・フローの概説」を参照してください。
標準JSFスコープに格納されているオブジェクト同様、pageFlow
スコープに格納されているオブジェクトもEL式を介してアクセスできます。pageFlow
スコープとの唯一の違いは、オブジェクト名にpageFlow
Scope
接頭辞を使用する必要があることです。たとえば、ボタンのラベルをpageFlow
スコープに格納されているマネージドBeanで指定し、ボタンが選択されるとBeanのメソッドがコールされるようにする場合は、ページに次のコードを使用します。
<af:button text="#{pageFlowScope.buttonBean.label}" action="#{pageFlowScope.buttonBean.action}"/>
pageFlowScope
は、Javaコードからアクセスできるjava.util.Map
オブジェクトです。setPropertyListener
タグでは、スコープにプロパティ値を設定でき、タグでリスニングするイベントを定義することもできます。たとえば、type
属性をaction
に設定したsetPropertyListener
タグを使用すると、ナビゲーション前にアクション・ソース(button
など)で値を設定する宣言的方法が提供されます。pageFlowScope
スコープとsetPropertyListener
タグを併用して、バッキングBeanにJavaコードを記述せずに、ページ間で値を受渡しできます。たとえば、setPropertyListener
タグとコマンド・コンポーネントを使用してpageFlowScope
スコープに値を設定するページと、テキスト・コンポーネントでpageFlowScope
スコープを使用して値を取得する別のページがある場合があります。
pageFlowScope
スコープを使用して、ダイアログなどの2つ目のウィンドウ間で値を設定することもできます。button
コンポーネントなどから2つ目のウィンドウを起動する場合、launchEvent
イベントおよびpageFlowScope
スコープを使用して、親プロセスの値をオーバーライドせずに2つ目のウィンドウとの間で値を受け渡すことができます。
pageFlow
スコープは、アプリケーションのJavaコード内からアクセスできます。終了したら、スコープを必ずクリアしてください。
注意:
アプリケーションでADFコントローラが使用されている場合は、スコープを手動でクリアする必要はありません。
始める前に:
オブジェクト・スコープに関する知識が役立つ場合があります。詳細は、「オブジェクト・スコープ・ライフサイクル」を参照してください。pageFlowスコープを使用して値を渡す方法についても理解する必要がある場合があります。詳細は、「ページ間の値の受渡し」を参照してください。
JavaコードでpageFlowScopeを使用する手順:
Javaコードを記述せずにpageFlowScope
スコープを使用するには、setPropertyListener
タグとコマンド・コンポーネントを組み合せて使用し、スコープに値を設定します。setPropertyListener
タグでは、リスニングするイベント・タイプを定義するtype
属性を使用します。このタイプに合致しないイベントはすべて無視されます。設定後は、ページ・フロー内の別のページからその値にアクセスできます。
ヒント
(以前のバージョンのADF Facesで使用されていた可能性がある)setActionListener
タグを使用するかわりに、setPropertyListener
タグを使用し、イベント・タイプをaction
に設定します。
pageFlowScopeスコープに値を設定する手順: