読者です 読者をやめる 読者になる 読者になる

スケのブログ

Java, Java EE, OpenAMなどの情報を記述していきます。

JSF(JavaServer Faces)ライフサイクルについて

JSF(JavaServer Faces)ライフサイクルについて

JSFアプリケーションはリクエストを受け取ってから、HTMLを描画するまでの一連の流れを定義しています。それを JSFライフサイクル」 といいます。
JSFライフサイクルは以下の図のように 6つのフェーズに分かれています。このページでは各フェーズの役割について、Java EE 6 Tutorial を参考に説明します。
JSFライフサイクルのフローは以下の図のように遷移していきます。

f:id:kenyoiii:20160330235709g:plain

ライフサイクルは以下の6つのフェーズに分類されます。

  • (1)Restore View フェーズ → 初回アクセスの場合、(6)へ
  • (2)Apply Request Values フェーズ
  • (3)Process Validations フェーズ → バリデーションエラーの場合、(6)へ
  • (4)Update Model Values フェーズ → エラーの場合、(6)へ
  • (5)Invoke Application フェーズ
  • (6)Render Response フェーズ

初回アクセスとポストバックアクセス

JSFのライフサイクルでは2種類のリクエスト(初回リクエスト、ポストバック)が存在します。
初回リクエストは、ユーザがページへ初回アクセスするときに発生します。ポストバックはユーザがページに2回目以降アクセスする場合に発生します。

初回リクエストの場合、ユーザの入力やアクションは実行されないので、「(1)Restore Viewフェーズ」と「(6)Render Responseフェーズ」のみ実行されます。
JSFページへの初回リクエストは、JSFコンポネントから生成されたリンクやボタンのクリックで発生します。
ページを描画するため、アプリは新規ビューコンポネントを作成し、 FacesContext に保存します。次に、アプリはビューから必要なオブジェクトを取得し、FacesContext.renderComplete() を実行します。
このメソッドは「(6)Render Responseフェーズ」へ強制的に遷移させ、描画を行います。上記図の「Response Complete」が書かれた矢印に相当します。
アプリが別のアプリにリダイレクトをしたい場合、JSFコンポネントを含んでいないレスポンスを生成したい場合、 FacesContext.responseComplete() を呼ぶ必要があります。

一方、ポストバックの場合、 FacesContext から前回保存を行った情報を使用し、バリデーション、モデル更新等を上記図の通り順序良く行っていきます。

ライフサイクルの順序で一つだけ例外があります。コンポネントのimmediate属性がtureを設定した場合、そのコンポネントと関連付くバリデーション、イベントは「(2)Apply Request Valuesフェーズ」で実行されます。

javax.faces.context.FacesContext について

javax.faces.context.FacesContext には1リクエストに関するすべての情報が含まれています。
アプリケーションのすべてのコンポネント、コンバータ、バリデータ、ハンドラはすべて FacesContext からアクセスすることができます。

各フェーズ詳細

(1)Restore Viewフェーズ(ビューの復元)

ビュー( UIViewRoot )の作成、ハンドラやバリデータのビューコンポネントとの関連付けを行い、そのビューを FacesContext に保存するフェーズです。
ページへ初めてアクセスした場合、JSFは空のビューコンポネントを作成し、「(6)Render Responseフェーズ」へ遷移します。リンクやボタンを押したときなど、サーバに要求が届いたときにこのフェーズが始まります。
ページへのアクセスがポストバック(2回目以降のアクセス)だった場合、JSFはクライアントやサーバに保存されている情報を使用し、 FacesContext からビューを復元を行います。

(2) Apply Request Valuesフェーズ(リクエスト値の適応)

クライアントからの送信値を「(1)Restore Viewフェーズ」で復元したビューコンポネントに適応させるフェーズです。
それぞれのコンポネントは decode(processDecodes()) を使用して保存を行います。各コンポネントに新しい値が設定され、メッセージやイベントがキューされます。

(3) Process Validationフェーズ(入力値の検証)

コンポネントに保存した値やコンポネント属性をバリデーター validate(processValidators) で検証を行います。
バリデーションに引っかかった場合、エラーメッセージを FacesContext に追加します。そして、「(6)Render Responseフェーズ」に遷移し、エラーメッセージを表示します。

(4) Update Model Valuesフェーズ(モデルの更新)

バリデーションを行ったコンポネントの値を、対応するモデル( JavaBean )に設定を行います。
値が JavaBean プロパティで指定した型に変換できない場合、「(6)Render Responseフェーズ」へ遷移し、エラーメッセージを描画します。

(5) Invoke Applicationフェーズ(アプリロジックの起動)

フォームのサブミット、ほかのページへ遷移するなど、アクションレベルのイベントを行います。

(6) Render Responseフェーズ(HTMLの生成)

前フェーズでコンポネントに設定された情報を元にHTMLレスポンスを生成します。
リクエストがポストバックであり、「(2)Apply Request Valuesフェーズ」、「(3)Process Validationフェーズ」または「(4)Update Model Valuesフェーズ」でエラーが発生した場合は、このフェーズへ遷移し、現在のページが再描画されます。
そのとき、ページに h:message , h:messages が含まれている場合、キューされていたエラーメッセージが表示されます。
ビューの内容が描画された後、次のリクエストがアクセスするための状態がレスポンスに保存されます。この保存された状態は「(1)Restore Viewフェーズ」で使用されます。

参考: https://docs.oracle.com/javaee/6/tutorial/doc/bnaqq.html#bnaqw