何でこうなるの?現場で起きた開発回顧録【その2-JSFライフサイクルとimmediate】

開発部の上條です。
やってきました、開発回顧録その2です。今回のお話は、前回の回顧録から続くお話になるので、そちらもお読みただけると一層ご理解いただけるかもしれません。
それでは、まいりましょう!

課題:「前の画面に戻れない…」

前回の回顧録から数日後のこと。システムの仕様が一部変更され、ホーム画面へ戻るためのボタンを入力画面に追加することになりました。
前回と同じ轍は踏むまいと、当時の私は「戻る」ボタンを以下のように実装していました。(javaファイルは前回と同様なので省略します)

この時は「これで動くはずだ!」と完全に思っている私。意気揚々と動作確認のためプログラムを実行してみます。

ここで「戻る」ボタンを押したら、しっかりと画面…が……?

「あれ?……………戻らない(T^T)」
またしても画面遷移ができません。前回実装した「登録」ボタンを押した際は、問題なく画面遷移ができているので、ajaxの使い方は問題ないようです。そうなると、なぜ今回追加した「戻る」ボタンでの画面遷移が上手くいかないのでしょうか?

この課題の原因は?

この課題の原因にはJSFのライフサイクルというものが関わっています。本来なら丁寧に全てご説明したいところですが、今回は必要な部分だけ簡潔にご説明しようと思います。
JSFでは、リクエストを受け取ってからレスポンスを返すまでの一連の処理の流れをライフサイクルと呼んでおり、以下の6つのフェーズで構成されています。

  1. ビュー(画面表示・入出力処理の実行部)の復元(Restore View)
  2. リクエストの値を適用(Apply Request Values)
  3. 入力値の検証(Process Validation)
  4. モデル(内部処理の実行部)の値を更新(Update Model Values)
  5. アクションイベントの処理(Invoke Application)
  6. レスポンス生成(Render Response)

この中で今回の問題に関係する点は、第3フェーズと第5フェーズの処理です。第3フェーズでは入力した値のデータ型や、その他指定した条件のチェックを行います。そのチェックに引っかかった場合は、第6フェーズまでスキップし元画面のレスポンスを返します。また、ActionやActionListenerで設定した処理は第5フェーズで実行されます。
以上を踏まえて、ソースコードを確認すると原因が見えてきます。「戻る」ボタンの実装で利用しているcommandButtonタグでは、action属性にて遷移先のURLを設定しているので、ライフサイクルの第5フェーズにて遷移先画面が指定されます。
しかし、各入力項目の実装に利用しているinputTextタグでrequired属性をtrueに設定しているため、各項目は入力必須となります。それにより、ライフサイクルの第3フェーズで必須入力チェックが行われることになります。必須入力項目が一つでも空欄のままだとチェックに引っかかってしまい、その場合は画面遷移の処理をスキップして元の画面を表示させます。
今回の原因はここにあります。入力チェックが「戻る」ボタンを押して処理を実行させた際にも実行されてしまっているのです!(試しに、必須項目を全て入力した上で「戻る」ボタンを押してみてください。この時は必須入力チェックをクリアしているので、問題なく画面遷移できることが確認できると思います。)
JSFのライフサイクルとしては正しい挙動なのですが、このままでは、いつまでも「戻る」ボタンでの画面遷移が実行できないので、これから修正していきましょう!

解決策は?

JSFライフサイクルに従い、入力チェックを画面遷移処理よりも先に実行しているため、「戻る」ボタンで画面遷移ができないことが判明しました。ならば、その処理順番を逆にすることができれば解決できそうです。
ここで登場するのがimmediate。これが有効になっている場合、通常は第5フェーズで行うAction処理などを第3フェーズの開始前に実行してくれます。このimmediate属性を以下のように「戻る」ボタンで有効にしてあげましょう。

なお、inputTextタグのrequired属性をfalseに変更することでも、戻るボタンの画面遷移自体は可能です。ただし入力チェックそのものが一緒になくなってしまうので、Javaファイルで別途入力チェックを実装する必要があるという点に注意しましょう。
ともあれ、これで「戻る」ボタンを押したらホーム画面にきちんと戻ってくれるはずです。早速テスト実行して確認しましょう。

「さて、どうだっ……?」

いいですね、想定通りの動きになりました!
こうしてJSFと画面遷移処理に対する理解を深めることができた私は、この先の開発を進めていくのでした…。
というわけで開発回顧録その2はここまでとなります。
前回・今回と画面サイド(フロントエンド)の実装に関するお話が続いたので、次回の回顧録では内部処理側(バックエンド)の実装で直面した課題について、何かお話しできればと思います。
それでは、今回もお読みいただきありがとうございました!

— Back Number —
何でこうなるの? 現場で起きた開発回顧録【その1 Ajaxと画面更新】
その他の「テクノロジー」カテゴリのブログ一覧

関連記事

  1. WPF Prism を使ってみた

  2. ワインのボトルに加速度センサー付きBeacon(ビーコン)を取り付けて…

  3. Beaconアプリ開発記【その4 画面表示編】

  4. ビーコンを使った出席管理アプリパッケージの使い方

  5. 知識ゼロで Unity をはじめてみた【その5 -Android 端末…

  6. 【C#】Modbus TCP クライアントサンプルを作成してみた