Webアプリケーションでは、ログインしたユーザーの情報など複数のリクエストにまたがって情報を保持する必要性があります。
Struts 1では、HTTPSessionを使用するのが通例ですが、HTTPSessionは原始的でありセッション取得の際のキャストが必須ですし、セッションに格納したデータを消し忘れてしまうこともあります。
JSFでは、「CDI(Contexts and Dependency Injection)」という仕組みを使用して、これらの課題に対処できます。CDIはJava EE標準の依存性注入とオブジェクトの生存管理に関する仕様です。いろいろな機能がありますが、今回はJSFに関係することだけを記述します。
リスト2ではバッキングBeanに「@RequestScoped」というアノテーションを付与していました。これはCDIによるオブジェクトの生存期間を決めるスコープアノテーションの指定で、自動的にオブジェクトの生成・破棄を適切なタイミングで行えます。
@RequestScopedは先ほど説明した通り、リクエストの発生のたびにバッキングBeanのインスタンスを生成します。他にも以下のようなスコープがあります。
例えば、リスト2のバッキングBeanを@RequestScopedから、@SessionScopedに変更すると、バッキングBeanはセッションに保存されるようになるため、セッション継続中は画面入力値が常に保持されるようになります。セッションに格納するキー名やオブジェクトの破棄などは気にする必要はありません。
また、セッションよりも短い生存期間のスコープもあるので、柔軟にデータの生存範囲を設定できます。
認証されたユーザーなどの複数のバッキングBeanで共有するようなデータを扱う場合は、CDIのBeanを作成してバッキングBeanでインジェクションします。
認証されたユーザーを示すCDIのBeanを作成します。スコープアノテーションがある以外はただのJavaクラスです(リスト6)。
/** * 認証されたユーザー */ @Named @SessionScoped public class User implements Serializable{ /** id */ private String id; //任意のプロパティを定義 }
バッキングBeanでは、@Injectアノテーションを使用すれば、このオブジェクトを取得できます(リスト7)。
@ApplicationScoped @Named public class HogenAction { // セッションスコープで管理されているオブジェクトを取得 @Inject private User user; public void someMethod() { // … } }
CDIを使用したセッション使用方法について解説しました。煩雑なセッション管理を容易にすることができると理解できたのではないでしょうか。
最後にJSFが向く分野やメリット・デメリットについてまとめます。
これまで見てきたように、JSFは高度なViewを構築することに特化したフレームワークといえます。コンポーネントによってHTTPやJavaScriptに詳しくなくても高度なViewを作成できますし、再利用性を高めることができます。この特徴は、多くの入力項目やボタンがあり、複雑なViewを作る必要があるシステムに向いています。
このようなシステムをアクションベースのフレームワークで実現するのは大変ですが、JSFではViewの入出力項目やイベントを直接バッキングBeanに結び付けることができますし、自作コンポーネントなどで再利用可能なViewを共通化することも可能なので、アクションベースよりも簡単に実装できます。
JSFはアクションベースのフレームワークと比較すると内部で複雑な処理を行っているため、性能面では後れを取る可能性があります。また、基本的にViewの状態をセッションに保存するためセッション領域も多く使用します。そのため、大量のアクセスが発生するアプリケーションでは性能要件を満たすか厳密に確認した方がいいでしょう。
また、Faceletsが出力するHTMLには、JSFを制御するための情報が含まれています。JavaScriptを使用する場合は、誤ってこれらの情報を消さないようにする必要があります。そのため、AngularJSのようなクライアントサイドでViewを構築するようなフレームワークとは、相性が悪いため、組み合わせない方がよいでしょう。
それ以外にも、JSFはView構築に特化しているので、JSFのみではWebサービスを提供できません。RESTなどのWebサービスを提供するには、JAX-RSなど別の技術を併用する必要があります。そのためには、ビジネスロジックをバッキングBeanに記述せずModel層のクラスに委譲しておくなどの工夫をしておくとよいでしょう。
JSFの初期バーションは設定ファイルが非常に多く、GUIツールによるViewの作成を想定していたため、Viewの作成効率も悪く、Struts 1と比較しても使いづらいフレームワークでした。JSFがいまひとつ流行していないのも、初期バージョンが使いにくかったのが主な原因ではないかと思います。
最近のバージョンから設定ファイルを可能な限り減らし、Facelets導入によりWeb技術とも親和性を増しており、魅力のあるフレームワークになっています。万能ではありませんが、使いどころに選べば、とても生産性の高いフレームワークだと思います。
今回はJSFの概要について紹介しました。JSFはStruts 1と比較して少ないコードでアプリケーションを構築できます。また、Ajaxによる差分更新も容易に実現でき、Viewの共通化や自作コンポーネントの作成などの拡張性も確保されています。
今回作成したアプリケーションのソースコードは筆者のGitHubで公開しています。本記事は重要なトピックのみを抜粋して紹介しましたので、ソースコードの全量については以下のGitHubリポジトリを参照してください。
次回は、Java EEのもう一つのフレームワークであるJAX-RSを紹介します。
ウルシステムズ シニアコンサルタント
金融系を中心に多数のシステム設計、構築を担当してきた。現在は顧客企業の若手社員を対象とした技術指導や、システム構築プロジェクトの技術支援を担当している。
「Enterprise Geeks」ではJava EEの記事を執筆中。
ここ最近の興味は、ドメイン駆動設計と関数型プログラミング。
Copyright © ITmedia, Inc. All Rights Reserved.