レベル: 中級 Yury Kats, Advisory Software Engineer, IBM
2009年 01月 06日 この記事では、IBM® Rational® Application Developer V7.5 を使用してカスタム JSF (Java™Server) コンポーネントを作成する方法を説明します。
JSF コンポーネント: その概要、そして誰にとって必要なのか
JSF フレームワークの長所の 1 つは、そのコンポーネント・ベースのアーキテクチャーです。コンポーネントとは、JSF 技術を使用して構築するあらゆる Web アプリケーションのビルディング・ブロックとなるもので、以下の役目を果たします。
- クライアントでの UI レンダリングを制御
- UI ウィジェットとバックエンド・データとのバインディングを制御
- サーバーへのポスト時にリクエスト・パラメーターをどのように処理するかを制御
- サブミットされた値の変換および検証方法を制御
- ユーザー・アクションに応答してイベントを起動
- その他
JSF 仕様とその実装は、アプリケーション開発者がそのまますぐに使用できる多数の基本コンポーネントを提供します。これらのコンポーネントには、何種類かの入力コンポーネント (inputText など) と出力コンポーネント (outputText など)、データ・テーブル、レイアウト・パネル (panelGrid など)、そしてボタン、リンク、画像などがあります。
コアとなる JSF 実装に用意されたこれらのコンポーネントを使用して有効な Web アプリケーションを構築することも可能ですが、このコンポーネント・セットには限界があります。最近の Web アプリケーションの設計では、リッチなユーザー・エクスペリエンスをもたらすことを目指すものですが、それには JSF 仕様が提供するコンポーネントよりも複雑なコンポーネントが必要になってくるからです。つまり、メニュー、リッチ・テキスト・エディター、ファイル・アップロード、カレンダーなど、ユーザーが期待する機能を提供するコンポーネントがなければなりません。
幸い JSF アーキテクチャーには柔軟性があり、JSF 実装に用意されたコンポーネントの他に、独自のコンポーネントを作成することができます。そのため、開発者たちは他のアプリケーション開発者の要求に対応する数々の JSF コンポーネント・ライブラリーを作成しました。今日の市場で人気を集めている優れたコンポーネント・ライブラリーには、以下のものがあります。
- IBM の JWL (JSF Widget Library)
- MyFaces の Tomahawk
- Trinidad および Tobago
- JBOSS の RichFaces
- ICEFaces
- その他多数
これらのライブラリーは非常に優れてはいるものの、開発者全員を満足させられるものは 1 つとしてありません。そのため、使用するライブラリーには存在しない、特定の JSF コンポーネントが必要になることが考えられます。
そんな場合に、「自分でコンポーネントを作成するべきかどうか」という考えが、おそらく開発者の頭をよぎることでしょう。
その答えは大抵の場合、「イエス」です。カスタム JSF コンポーネントを作成することが適切な手段となることは珍しくありません。カスタム・コンポーネントを作成すれば、多くの機能を 1 つの JSF タグにカプセル化することができます。そのタグは、さまざまなページやアプリケーションで再利用したり、組織内の他の開発者たちと共有することもできます。さらに、カプセル化した機能は 1 箇所で維持されるため、アプリケーションのあちこちのページに機能が分散されている場合に比べて保守が容易になります。
例えば、アプリケーションでユーザーの住所情報を収集しなければならない場合を想定してみてください。ユーザーの自宅の住所、勤務先の住所、配送先住所、請求先住所が関心の対象となる可能性は十分考えられるため、このような情報を収集する必要が出てくることは、1 度きりではないはずです。よく使われているコンポーネント・ライブラリーを調べてみると、住所を処理するコンポーネントが含まれているライブラリーは 1 つも見当たりません。そこで、標準 JSF コンポーネントを利用して、さまざまな入力フィールドと出力フィールドから住所のフォーム (図 1) を素早く作成することにしました。
図 1. 住所ブロック
このような住所ブロックは複数のページで必要になるため、さまざまなページ、さらには異なるアプリケーションでもこの作業を繰り返します。これでページは正常に機能するのでしょうか?答えは「機能する」です。同じようなコードを何度も繰り返すことになるのでしょうか?その通りです。保守は悪夢のような作業になりますか?当然です。1 週間後にフィールドを再編成したり、国のフィールドを追加しなければならなくなったりした場合はどうなるのでしょう?その場合には、この住所ブロックを作成したすべてのページの 1 つひとつを変更しなければなりません!
それよりも遙かに便利な方法は、このブロック全体をラップする独自のコンポーネントを作成し、あらゆる場所で <my:inputAddress value="#{address}" /> といった 1 つの共通タグを使うことです。こうすれば、かなり短くて簡潔な JSP のソース・コードとなり、しかも住所ブロックを変更する必要が出てきたら、1 箇所で変更すればよいだけとなります。さらに、このようなコンポーネントを必要とする誰もが利用できるように、この inputAddress コンポーネントは作業仲間やオンライン・コミュニティーと共有することも可能です。
ここまでの説明で、カスタム・コンポーネントを作成することが有効であることは明らかなはずですが、それではカスタム・コンポーネントを作成する最善の方法は何でしょう?JSF 仕様では新しいコンポーネントの作成を可能にしていますが、その作業はそれほど単純ではありません。コンポーネントを作成するには、以下の 3 つの Java クラスを作成する必要があります。
- コンポーネント・クラス
- レンダラー・クラス
- タグ・ハンドラー・クラス
上記のクラスに加え、新しいコンポーネントに関する情報を faces-config.xml ファイルと tag library ファイルに提供しなければなりません。これでは面倒で、間違いを起こしやすい作業となってしまいます。
このような理由から、Rational Application Developer V7.5 では JSF 開発者がカスタム・コンポーネントを素早く簡単に作成できるようにする新機能を導入しています。コンポーネントの作成者は、使い慣れた Rational Application Developer のツール (パレットからのドラッグ・アンド・ドロップ、WYSIWYG エディター、Properties ビュー、PageData ビューなど) を使って、必要なすべての Java クラスと構成ファイルを Rational Application Developer で自動的に作成することができます。
上級ユーザーはもちろん今まで通り、生成された Java クラスを自分で調整して一層強力で柔軟性に優れたコンポーネントに仕上げることができます。しかし、Rational Application Developer でコンポーネントを作成する場合には、内部の JSF アーキテクチャーを知る必要はありません。
この新機能を明らかにするため、これから単純なカスタム JSF コンポーネントを作成します。その対象は、ラベルの付いた入力フィールドという、ごく一般的なケースです (リスト 1)。
リスト 1. ラベル付き入力フィールド
<h:outputText value=”Name:” / >
<h:inputText value=”#{person.name}” />
|
上記のようなペアは、JSF アプリケーションでよく見かけるもので、図 1 に示した住所ブロックでも 3 回使用されています。この 2 つのタグを単一の有効なコンポーネントのなかにラップします (リスト 2 を参照)。
リスト 2. 有効なコンポーネント
<my:inputLabel value=”#{person.name}” label=”Name:” />
|
カスタム JSF コンポーネントの作成方法
JSF コンポーネントが単独で存在することはめったにありません。一般に JSF コンポーネントは、コンポーネント・ライブラリーの一部となっています。このライブラリーに集められているコンポーネントは、任意のアプリケーションで利用することができ、再利用や共有が可能なものになっています。通常、ライブラリーは単一の Java™ アーカイブ (JAR) ファイルになっており、このファイルには多数のコンポーネントと、そのライブラリーを使用するために必要なすべての構成ファイルが含まれています。コンポーネント・ライブラリーの例としては、IBM の JWL、MyFaces の Tomahawk、JBOSS の RichFaces があります。
したがって、カスタム・コンポーネントを作成するためにはまず、コンポーネント・ライブラリーを作成する必要があります。
コンポーネント・ライブラリーを作成する
コンポーネント・ライブラリーを作成する手順は、以下のとおりです。
- File > New > Project の順に選択します。
- Web カテゴリーには、Faces Component Library Project を選択します。
- Next をクリックします。
上記の操作によって、New Faces Component Library ウィザードが開きます。このウィザードは、新規の Web プロジェクトを作成するときに使うウィザードとよく似ていることに注目してください。唯一の違いは、Configuration フィールドが Faces Component Library に設定されていることだけです (図 2 を参照)。学習時間が最小限になるように、Rational Application Developer のカスタム JSF コンポーネント用ツールは全体的に、ユーザーが使い慣れている標準的な Web および JSF ツールと極めて似通った設計になっています。
図 2. New Faces Component Library ウィザード
- ライブラリーの名前 (この例では
MyComponents) を入力した後、Finish をクリックします。
- 上級ユーザーは、Finish をクリックする前に Next ボタンを 3 回クリックして、ライブラリー設定のいくつかを調整することもできます。調整できる設定項目は、ライブラリーの URI、接頭辞、そして生成された Java クラスのパッケージ名です (図 3 を参照)。
図 3. Component Library settings ダイアログ
コンポーネントを作成する
- ライブラリー・プロジェクトを作成したら、Enterprise Explorer ビューでプロジェクトの名前を右クリックして、New > Faces Custom Component の順に選択します。
すると New Custom Component ウィザードが開きます。このウィザードの場合も通常の Web ページを作成するウィザードとほとんど同じですが、ページをカスタム Faces コンポーネントとして識別するために、特殊なテンプレートを選択するという点だけが異なります (図 4 を参照)。
図 4. 新規カスタム・コンポーネント
- 新規コンポーネントの名前 (この例では
inputLabel) を入力した後、Finish をクリックします。
Finish をクリックすると、Rational Application Developer が JSP ファイルを作成してエディターに開きます。ユーザーはこのファイルを使用して、コンポーネントを設計することができます。このファイルは通常の JSP ファイルに過ぎません。つまり、ファイルを操作するときには、以下のお馴染みの Rational Application Developer ツールをすべて使用できるということです。
- Palette ビュー
- Properties ビュー
- QuickEdit ビュー
- PageData ビュー
ただしカスタム・コンポーネントは通常の JSF ページとは異なり、<BODY> タグや <f:view> タグを使用しません。これらのタグの代わりに使用する特殊な <jsfc:component> タグには、カスタム・コンポーネントを構成する他の JSF タグが含まれます。
Enterprise Explorer ビューで、作業中のライブラリー・プロジェクトを確認してみてください。前の手順で作成したコンポーネント JSP ファイルだけではなく、ライブラリー内には Rational Application Developer によって他にもいくつものファイルが生成されていることがわかります (図 5 を参照)。
図 5. 生成されたファイル
生成されたファイルには、以下のものがあります。
- コンポーネント・クラス (InputLabelComponent.java)
- JSP タグ・ハンドラー (InputLabelTag.java)
- レンダラー・クラス (CustomComponentRenderer.java)
- 構成ファイル: faces-config およびタグ・ライブラリー (faces-config.xml)
- すべてのコンポーネント成果物が含まれるライブラリー JAR ファイル (MyComponents.jar)
- コンポーネントのテスト・ページ (testInputLabel.jsp)
コンポーネント定義が含まれる JSP ファイル (この例では inputLabel.jsp) を変更すると、Rational Application Developer はその度に、コンポーネント・ライブラリーが機能するために必要なその他すべてのファイルを自動的に再生成します。そして再生成したファイルを、1 つの JAR ファイルにパッケージ化します。この JAR ファイルが、後で別のプロジェクトで使用したり、他のユーザーと共有したりすることができる実質上のコンポーネント・ライブラリーになります。また、Rational Application Developer はテスト・ページも生成します。このテスト・ページを使用して、サーバーにデプロイされたカスタム・コンポーネントがどのように動作するかを確認することができます。
コンポーネントを構成する
新しいコンポーネントの作成が完了したところで、次はコンポーネントの属性とプロパティーを構成します。
- エディターに開かれているコンポーネント定義ページ (inputLabel.jsp) に戻り、
<jsfc:component> タグを選択します (Source ビューでタグをクリックするか、Design ビューに表示されている点線の枠内をクリックします)。
これで、Properties ビューを使用して、この新規コンポーネントの構成に取り掛かることができます (図 6 を参照)。
図 6. コンポーネントのプロパティー
- Properties ビューでは、以下の設定を構成することができます。
- Tag name には、コンポーネントのタグ名を入力します。デフォルトでは、タグの名前は作成した JSP と同じ名前になりますが、この 2 つが同じ名前である必要はありません。
- Description には、コンポーネントの他のユーザーに役立つように、コンポーネントについての説明を入力します (他のユーザーとコンポーネントを共有することにした場合)。
- Component behaves as には、コンポーネントの振る舞いを指定します。JSF 仕様では、カスタム・コンポーネントの振る舞いに適用できる標準コンポーネントをいくつか定義しています。選択肢としては Basic JSF component の他、Input component、Multi-Select component、Command component があります。これらの選択肢からいずれかを選択すると、Rational Application Developer は自動的に、選択されたコンポーネント・タイプに標準的な属性を生成し、選択された振る舞いをサポートするコードをコンポーネント・クラスに生成します。
- Attributes には、コンポーネントの属性を追加します。
- Do not overwrite generated Java classes when this JSP changes を選択すると、この JSP が変更されても、既に生成されている Java クラスを Rational Application Developer が上書きしないように設定することができます。このオプションは、上級ユーザーがコンポーネント・クラスの生成後に手動でクラスを調整する場合に役立ちます。この場合、JSP でのコンポーネント定義はコンポーネントの Java ソースとは違ったものにすることができます。
この例での inputLabel コンポーネントについては、入力コンポーネントとして振る舞うように構成し、ラベル属性と値属性の 2 つを追加します。
- 属性を追加するには、Properties ビューで Add ボタンをクリックし、属性の Name および Class を入力します (図 7 を参照)。追加する属性のクラスは、どちらも
java.lang.String です。
図 7. 属性の追加
構成が完了した時点で、inputLabel コンポーネントの Properties ビューの内容は図 8 のようになっているはずです。
図 8. 構成後のコンポーネント
このビューで注目すべき点は、コンポーネントは入力コンポーネントとして振る舞うように設定されたため、Rational Application Developer は自動的に入力コンポーネントの標準的な属性として、immediate、required、valueChangeListener を追加したことです。
コンポーネントのコンテンツを作成する
今度は、この inputLabel コンポーネントの実際のコンテンツを定義する番です。前述のとおり、このコンポーネントでは outputText でラベルを表示し、それに続く inputText で値を表示するようにします。
- Palette から Output および Input コンポーネントをページにドラッグします。
- PageData ビューの属性を Design ビューのコンポーネントにドラッグするという方法で、Output コンポーネントを
label 属性にバインドし、Input コンポーネントを value 属性にバインドします (図 9 を参照)。
図 9. コンポーネントのコンテンツ作成
Properties ビューで構成したカスタム・コンポーネントの属性は、PageData ビューの Faces component カテゴリーにもリストされていることに注目してください。
コンポーネントの属性を別のコンポーネントにバインドすると、実行時にこの属性にアクセスするための特殊な JSF 式、#{component.attribute} が生成されます (図 10 を参照)。
図 10. コンポーネントのソース
これはつまり、後でこのコンポーネントを例えば <my:inputLabel value=”#{person.name}” label=”Name:” /> のように使用すると、outputText の値は “Name:” となり、inputText の値は #{person.name} となるということです。
新しいコンポーネントのコンテンツを定義する作業は、これですべてです。ページを保存すると、Rational Application Developer がすべての必要な成果物を更新し、コンポーネント・ライブラリーが使用できる状態になります。
コンポーネントをテストする
新規コンポーネントの作成が完了したら、実際のアプリケーションで使用する前、あるいは他のユーザーと共有する前に、このコンポーネントをサーバーで実行して、どのように振る舞うかをテストする必要があります。その目的で、Rational Application Developer はテスト・ページ、testInputLabel.jsp を作成しています。このテスト・ページは新しいコンポーネント・タグが含まれる標準の JSP なので、これをサーバーにデプロイすれば、新規コンポーネントの動作を確認することができます。
- testInputLabel.jsp ファイルを開きます。このページのソースには 1 つの
<m:inputLabel> タグしか含まれていないものの、Design ビューには新規コンポーネントに含まれる outputText と inputText が表示されていることに注目してください (図 11 を参照)。Properties ビューには、前の手順で追加した label および value 属性を含め、inputLabel コンポーネントの属性がすべてリストされます。QuickEdit には Value Changed イベントが示されます。これは、入力コンポーネントとして振る舞うように新規コンポーネントを構成したからです。
図 11. コンポーネントのテスト・ページ
- Properties ビューを使用して、
label 属性と value 属性に何らかの値を入力してからページを保存します。その上で、このページをサーバーで実行してください。
ブラウザーを開くと、ラベルに続いて入力フィールドが表示され、その両方にコンポーネントの属性に指定した値が示されていることがわかります (図 12 を参照)。
図 12. サーバーでの実行
これで、Rational Application Developer ツールを使用して作成した新規 JSF コンポーネントが完全に機能すると確認できました。
Web アプリケーションでのカスタム・コンポーネントの使用方法
出来上がった真新しい JSF コンポーネント・ライブラリーは、Web アプリケーションで使用することも、作業仲間と共有することもできます。
Rational Application Developer は自動的に、コンポーネント・ライブラリーに属するすべてのものを 1 つの JAR ファイルにパッケージ化します。このファイルは自分で使うことも、他のユーザーに配布することもできます。ただし、Rational Application Developer のツール機能を最大限に利用するには、このライブラリー用のライブラリー定義を作成する必要があります。カスタム・コンポーネント・ライブラリーに対する Rational Application Developer のサポートについての簡潔な説明は、「参考文献」セクションを参照してください。
ライブラリー定義を作成する
作成したライブラリーを対象に、以下の手順に従ってライブラリー定義を作成します。
- Enterprise Explorer ビューで、ライブラリー・プロジェクト (MyComponents) を右クリックします。
- New > Faces Library Definition の順に選択します。
- 表示された Create Faces Library Definition ウィザード (図 13) で、以下の作業を行います。
- ライブラリー名 (この例では
MyLibrary) を入力します
- ライブラリー・プロジェクトが選択状態になっていることを確認します。
- Finish をクリックします。
図 13. ライブラリー定義
Rational Application Developer がライブラリーの処理を完了すると、エディターが開きます。このエディターで、新規に作成したライブラリーとコンポーネントに対するツール・サポートの以下のすべての側面をカスタマイズすることができます。
- Palette に表示する内容
- コンポーネントを可視化する方法
- ドラッグ・アンド・ドロップ操作中の動作
- その他多数
- ライブラリー定義のカスタマイズについてはこの記事の範囲外なので、ここでは Rational Application Developer がこの定義のために作成した内容を受け入れて、エディターを閉じます。
ライブラリー定義が作成できました。これで、新しいライブラリーを通常の Web プロジェクトで使い始めることも、他のユーザーとこのライブラリー定義プロジェクト (MyLibrary) を共有することもできます。
Web アプリケーションでカスタム・コンポーネントを使用する
- Faces プロジェクトの構成を使用して新しい動的 Web プロジェクトを作成し、そのプロジェクト内で新規 Web ページを作成します。
Web ページをエディターに開くと、Palette には、標準 Rational Application Developer パレット・ドロワーすべてがリストされた後に、新規コンポーネント・ライブラリーと新しく作成したコンポーネントが有効になっていることがわかります。
図 14. Palette
- Palette からページに
inputLabel コンポーネントをドラッグします。この新規ライブラリーをこの Web プロジェクトで使用するのはこれが初めてなので、カスタム・コンポーネントが含まれる JAR ファイルをプロジェクトにコピーする必要があります。
- Rational Application Developer が、コピーの確認を求めるプロンプトを出します。OK をクリックして確認します。
前に説明したテスト・ページでの場合と同じく、Web ページのソースには <m:inputLabel> タグが追加されています。先の図 11 に示したように、このタグは、Design ビューでは outputText コンポーネントと inputText コンポーネントのペアとして視覚化されます。このタグの属性は Properties ビューで選択可能で、Value Changed イベントのスクリプトの作成は QuickEdit ビューで行うことができます。
- ページをサーバーで実行すると、前に図 12 に示したコンポーネント・レンダラーをブラウザー内で確認できるはずです。
これで、Web プロジェクトでカスタム JSF コンポーネントを使用する手順は正常に完了しました。
ダウンロード | 内容 | ファイル名 | サイズ | ダウンロード形式 |
|---|
| Sample projects and components | SampleProjects.zip | 9412KB | HTTP |
|---|
参考文献 学ぶために
製品や技術を入手するために
議論するために
著者について  | 
|  | Yury Kats は、IBM Rational Application Developer チームで JSF の実装、コンポーネント、ツールに取り組んでいる開発者です。 |
記事の評価
|