[特別企画] JavaServer Facesを理解する(後編) |
JSFによるWebアプリケーション開発 |
モデルとビジネスロジック |
■モデル、ビジネスロジッククラスの実装
まず、データを保持するモデルから説明しましょう。データを保持するためのクラスは、選択した車と、車のオプションに関する情報を保持するCurrentOptionServer、クレジットカード番号などの情報を保持するCustomerBeanです。CurrentOptionServerは、初期ページ(Storefront.jsp)で選んだ車種とオプション選択画面(more.jsp)で選択したパッケージ、オプションに関する情報を保持するためのクラスです。このクラス内ではJSFのAPIも使用していますが、このAPIについては後ほど解説します。
初期ページ(Storefront.jsp) |
オプション選択画面(more.jsp) |
次にユーザーのアクションに応じたビジネスロジックを実行する2つのクラスを説明しましょう。前回説明したように、JSFはイベントリスナーモデルを使用しており、Actionイベントとvalue-changedイベントの2つのイベントをサポートしています。Actionイベントは、UICommandで表現されるボタンやリンクをユーザーがクリックした場合に発生し、javax.faces.event.ActionListenerの実装クラスにおいてイベントを処理します。CarActionListenerは、このActionListenerをインプリメントしたクラスです。
また、value-changedイベントは、UIInputやそのサブクラスのコンポーネントの値が変化した場合に発生し、javax.faces.event.ValueChangedListenerの実装クラスにおいてイベントを処理します。
ActionListenerの実装クラスでは、getPhaseId()とprocessAction(actionEvent)の2つのメソッドを定義します。getPhaseIdメソッドは、ライフサイクルのどの段階でこのイベントが処理されるかの識別子を指定します。リスナーは、この識別子で定義された処理が完了してから処理を実行します。ここでは、「PhaseId.APPLY_REQUEST_VALUES」を指定しており、Apply Requestフェイズが完了した後に、イベントが処理されることを指定しています。
リスト1 getPhaseIdメソッドpublic PhaseId getPhaseId() { |
そして、processActionには発生したイベントに対して行う処理を実装します。CarActionListenerでは、Storefront.jspにおける車の選択、more.jspにおけるパッケージの選択、費用の再計算などに対するイベントを処理します。processActionでは、引数として受け取ったjavax.faces.event.ActionEventからJSFタグ内で指定されたcommandNameを受け取り、このコマンドに応じた処理を呼び出します。例えば、commandNameが「deluxe」の場合(more.jspページにおいて、パッケージとして「Deluxe」を選択)は、processActionからprocessDeluxeを呼び出し、このメソッド内で処理を行っています。
リスト2 processActionメソッドpublic void processAction(ActionEvent event) { |
パッケージにDeluxeを選択したところ |
次に、processDeluxeメソッド内の処理について説明します。processDeluxeでは、初めにActionEventからこのアクションを生成したUIコンポーネントを取り出しており、このUIコンポーネントを通して、コンポーネントツリー内のほかのUIコンポーネントを取得することができます。
例えば、component.findComponent("securitySystem")を実行した場合、more.jspにおいて車のオプション「SecuritySystem」を選択するためのチェックボックスとして使用されているコンポーネントを取得します。
private void processDeluxe(ActionEvent event, ResourceBundle rb) { |
次の、FacesContext.getCurrentInstance()では、javax.faces.context.FacesContextを取得しています。FacesContextは、1つのRequestとそれに対応するResponseに関する状態を保持しており、検証がエラーとなった場合のメッセージなども、ユーザーへのResponseとしてFacesContextに対して設定します。ここで取得したFacesContextは、この後CurrentOptionServerの値の取り出し、更新のために使用しています。
FacesContext context = FacesContext.getCurrentInstance();
|
次にWebアプリケーションを表すjavax.faces.application.Applicationを取得します。Applicationインスタンスは、javax.faces.FactoryFinderのgetFactoryメソッドによりjavax.faces.application.ApplicationFactoryを取得し、このApplicationFactoryのgetApplication()を呼び出すことで取得します。そして、ApplicationクラスのメソッドgetValueBindingの引数に、CurrentOptionServer.engineOptionを指定することにより、CurrentOptionServerのengineOptionプロパティ値を表すjavax.faces.el.ValueBindingオブジェクトを取得します。ValueBindingオブジェクトを取得した後は、FacesContextを通しgetValueメソッドによるモデルプロパティ値の取得、setValueによる値の更新が可能です。
JSFでは、このように、FacesContext、Applicationを取得後、ValueBindingオブジェクトをApplicationから取得し、モデルのプロパティ値の取得、更新を行います。
ApplicationFactory factory = (ApplicationFactory)FactoryFinder.getFactory( |
また、このメソッド内では、上記以外に各種UIコンポーネントの取得や特定のUIコンポーネントへのプロパティの設定などを行っていますが、細かい説明については省略します。実際のアプリケーションの動作から、内容を確認してください。
リスト3 processDeluexメソッド全体private void processDeluxe(ActionEvent event, ResourceBundle rb) { |
次にPackageValueChangedクラスを説明します。ActionListenerの場合と同様に、ValueChangedListenerにおいてもgetPhaseIdを実装し、イベントが処理されるべきフェイズを指定します。また、ValueChangedListenerでは、processValueChanged(valueChangedEvent)メソッドにおいて発生したValueChangedEventに対する処理を実装します。
processValueChangedでは、初めにValueChangedEventを発生させたコンポーネントのIDを取得し、次にCurrentOptionServerから現在の車の値段を取り出しています。そして、コンポーネントの変更に応じて値段を計算し、結果をCurrentOptionServerに更新します。また、このクラス内でもJSFのAPIを使用していますが、CarActionListener内で説明したものと同様の処理を行っているので説明を省略します。
リスト4 PackageValueChanged.javapublic class PackageValueChanged implements ValueChangedListener { |
■コンフィグレーションファイルの設定
次に、ここまでで紹介したクラスをJSFアプリケーションとして利用するために必要な定義について説明しましょう。
JSFでは、ビーンをアプリケーション設定ファイルである「faces-config.xml」に登録することによってインスタンス化することが可能です。JSF実装はアプリケーション起動時にfaces-config.xmlの定義を読み込み、ビーンを初期化し、指定されたスコープ内に保存します。ちょうど、JSP内でuseBeanアクションを使用してインスタンス化するのと同じことが、定義ファイルを使用して行えるわけです。
アプリケーションにおいて必ず必要なビーンに関しては、従来のようにページからインスタンス化するのではなく、設定ファイルからインスタンス化することにより、意図しないページアクセスにも対応できるでしょう。
そのほかのクラスについて特に設定の必要はありませんので、設定ファイルの定義は以上です。
<managed-bean> |
2/4 |
INDEX |
||
JavaServer Facesを理解する(後編) | ||
Page1 JSFアプリケーションの構築 |
||
Page2 |
||
Page3 カスタムコンバータ、カスタムバリデータ、タブハンドラ |
||
Page4 UIコンポーネント、JSFタグライブラリを使用したJSPの作成 ページナビゲーションの定義 まとめ |
INDEX | |
特別企画:JavaServer Facesを理解する | |
前編 JSFの構造を理解する | |
後編 JSFによるWebアプリケーション開発 |
連載記事一覧 |
- 実運用の障害対応時間比較に見る、ログ管理基盤の効果 (2017/5/9)
ログ基盤の構築方法や利用方法、実際の案件で使ったときの事例などを紹介する連載。今回は、実案件を事例とし、ログ管理基盤の有用性を、障害対応時間比較も交えて紹介 - Chatwork、LINE、Netflixが進めるリアクティブシステムとは何か (2017/4/27)
「リアクティブ」に関連する幾つかの用語について解説し、リアクティブシステムを実現するためのライブラリを紹介します - Fluentd+Elasticsearch+Kibanaで作るログ基盤の概要と構築方法 (2017/4/6)
ログ基盤を実現するFluentd+Elasticsearch+Kibanaについて、構築方法や利用方法、実際の案件で使ったときの事例などを紹介する連載。初回は、ログ基盤の構築、利用方法について - プログラミングとビルド、Androidアプリ開発、Javaの基礎知識 (2017/4/3)
初心者が、Java言語を使ったAndroidのスマホアプリ開発を通じてプログラミングとは何かを学ぶ連載。初回は、プログラミングとビルド、Androidアプリ開発、Javaに関する基礎知識を解説する。
|
|