X

An Oracle blog about WebLogic Channel

[連載] WebLogic Server 12cでJava EE 6を動かしてみよう!(2) JSF 第1回

実践! Java EE 6 ロゴ

本連載では、サンプル・アプリケーションの開発を通じて Java Platform, Enterprise Edition 6 (Java EE 6)の仕様とその魅力をお伝えすることを目的としています。
今回から2回にわたって、 JavaServer Faces (JSF) をとりあげます。現在は Web ベースの企業システムが広く普及していますが、リッチなユーザー・インタフェースへのニーズの高まりやスマートフォン/タブレットなどのマルチチャネル・アクセスなど、アプリケーションの複雑性は増す一方です。
JSF は Java EE における Web アプリケーション開発のための標準フレームワークです。
今回は、 JSF を利用することで Web アプリケーション、特にユーザー・インタフェース開発がどのように効率化できるかを説明します。(日本オラクル Fusion Middleware 事業統括本部 智野潤子)

JSF の特長

JSF は MVC モデル2に基づいたフレームワークです。
MVC モデル2に基づいた Web アプリケーション開発フレームワークは、 Apache Struts など、これまでにも数多く提供されてきました。
JSF が旧来のフレームワークと異なるのは、ユーザー・インタフェースの開発を効率化することにフォーカスしている点です。
JSF の特長は次のようにまとめることができます。


  • UIコンポーネントの提供
    JSF では、ボタンや入力フォームなどユーザー・インタフェースを構成する部品を「UI コンポーネント」として提供しています。
    UI コンポーネントは、拡張性、再利用性が十分に考慮されて設計されています。
    また、プロパティの設定値によって振る舞いや見た目をカスタマイズできることから、カスタム・タグやスクリプトレットを中心とした旧来の Web アプリケーション開発と比べて IDE (統合開発環境)との親和性がとても高いです。
  • サードパーティ製の UI コンポーネントの利用
    JSF の実装が提供する UI コンポーネントだけでなく、サードパーティ製の UI コンポーネントも提供されます。
    例えば、オラクルでは ADF Faces という JSF コンポーネント群を提供しています。
    ADF Faces は、ツリーやグラフ、ピボット・テーブルなど、JSF 標準の UI コンポーネントにはない、高度な UI コンポーネントを多数提供しています (Oracle ADF Faces Hosted Components Demo では、実際に ADF Faces を利用したサンプル・アプリケーションが公開されています)。
  • イベント・ドリブンなプログラミング・モデル
    UI コンポーネントは、「ボタンが押された」「テキスト・フィールドの値が変わった」といった「イベント」を処理する機能を提供します。
    このイベント・ドリブンなプログラミング・モデルを採用した JSF は、 HTTP リクエスト/レスポンスを強く意識する必要があった旧来の Web アプリケーションよりも、 Ajax を活用しやすいです。

JSF は Java プラットフォームの標準化プロセスである Java Community Process(JCP) によって仕様が策定されています。
Java EE 6に採用されているJSF 2.0はJSR-314で規定されています。
JSF 2.0では、Facelets の導入やアノテーションのサポート、ページ・ナビゲーション機能の改善など、強力な新機能が追加されました。
今回は、JSFの基本的な機能に加えて JSF 2.0の主要な新機能についても説明していきます。

作成するアプリケーション

今回から2回にわたって作成するアプリケーションは、数字当てゲームです。ルールと処理の流れは次のとおりです。

図1: アプリケーションの動作イメージ
図1: アプリケーションの動作イメージ(クリックして拡大)

  1. ユーザーがアプリケーションにアクセスすると、開始ページが表示されます。
  2. ユーザーは開始ページに名前を入力し、「開始」ボタンをクリックします。
    • 名前の入力は必須です。
    • 名前が5文字未満の場合は、再入力を求められます。
  3. サーバー上で正解の数字が生成され ゲーム・ページが表示されます。
  4. ユーザーはゲー���・ページに0から9までの整数から3つを入力します。
    • 「077」「888」のように同じ数字を1度に2回以上入力することはできません。
    • 数字以外の文字を入力した場合は再入力を求められます。
  5. ユーザーが「回答」ボタンをクリックすると、入力した数字がサーバーに送信され、正解の数字とを比較します。
  6. ユーザーが入力した数字が正解の場合は、ゲーム・ページに正解だったことを知らせるメッセージが表示されます。
  7. ユーザーが入力した数字が不正解の場合は、ヒントとして数字と順番が合っていた個数(Hit)、数字は合っているが順番は合っていない個数(Blow)が表示されます。
    • 正解が「012」、ユーザーが入力した数字が「024」の場合は「1 Hit/1 Blow」
  8. ユーザーが入力した数字と Hit/Blow の数は回答履歴に残ります。
  9. 「やり直し」ボタンをクリックすると、最初の画面に戻ります。

今回は次の機能を実装していきます。


  • 開始ページとゲーム・ページの共通部分を定義したページ・テンプレートの作成
  • 開始ページの作成
  • ゲーム・ページの作成
  • データの受け渡しの設定
  • ページ・ナビゲーションの設定

アプリケーション開発の準備

本連載では、 Oracle Enterprise Pack for Eclipse (OEPE) を使用してサンプル・アプリケーションの開発を進めます。
OEPE や WebLogic Server 12c のインストールおよび設定が終わっていない方は、前回の記事「[連載] WebLogic Server 12cでJava EE 6 を動かしてみよう!(1) 概要」を参考にしてください。

ここでは、Eclipse のプロジェクトを作成します。
Eclipse のメニュー・バーから「New」→「Dynamic Web Project」を選択します。
「New Dynamic Web Project」ウィンドウが表示されたら、「Project Name」として「jsfsample」、「Configuration」として「JavaServer Faces v2.0 Project」を選択し、「Finish」ボタンをクリックします。

図2: 「New Dynamic Web Project」ウィンドウ
図2: 「New Dynamic Web Project」ウィンドウ(クリックして拡大)
プロジェクトが作成されると、次のファイルが自動的に作成されています。

  • WebContent/index.xhtml
    デフォルトのJSFページです。
  • WebContent/WEB-INF/faces-config.xml
    JSF の構成ファイルです。エラー・メッセージの国際化などに使用するリソース・バンドルの情報が記述されています。
  • WebContent/WEB-INF/web.xml
    JSF のフロント・コントローラの役割を担う FacesServlet の定義情報が記述されています。
  • WebContent/WEB-INF/weblogic.xml
    WebLogic Server 固有のデプロイメント・ディスクリプタです。
  • src/resources/application.properties
    faces-config.xml に登録されたリソース・バンドルのソースです。

ページ・テンプレートの作成

JSF 1.2 までは、ページをJSPで記述する必要があり、UI コンポーネントは JSP のカスタム・タグ・ライブラリの形式で提供されていました。
JSP と JSF はリクエストを処理するライフサイクルが異なるので、HTML タグと UI コンポーネントが混在しているようなページでは、開発者が意図したデザインにならないことがありました。

JSF 2.0 では、Facelets という XML ドキュメントでページを定義します。
Facelets が導入されたことで、JSF 1.2においてJSPに起因する問題が解消されるだけでなく、JSP コンパイラによるオーバヘッドが発生しないので、パフォーマンス向上の効果も期待できます。

また、Facelets はページの共通部分を外出しにするテンプレートを作成することができます。
今回は HTML タグを使用して Web ページのレイアウトを定義するので、 Facelets は XHTML 形式で作成します。テンプレートには、次の3つを定義します。


  1. ページごとに定義された「title」によってページ・タイトルを指定
    ui:insert タグ)
  2. すべてのページで共通のページ・ヘッダー
  3. ページごとに定義された「content」を表示
    ui:insert タグ)

XHTML ファイルを作成するには、Eclipse のメニュー・バーから「File」→「New」→「XHTML Page」を選択します。
「New XHTML Page」ウィンドウの「HTML」画面では、「Enter or select the parent folder」に「jsfsample/WebContent」を、「File name」に「template.xhtml」と入力して、「次へ」をクリックします(図3)。

「New XHTML Page」ウィンドウの「Select XHTML Template」ページでは、「Use HTML Template」をチェックし、「New JavaServer Faces (JSF) Page (XHTML)」を選択して「Finish」をクリックします(図4)。






図3: 「New XHTML Page」ウィンドウ 「HTML」ページ
図3: 「New XHTML Page」ウィンドウ
「HTML」ページ(クリックして拡大)
図4: 「New XHTML Page」ウィンドウ 「Select XHTML Template」ページ
図4: 「New XHTML Page」ウィンドウ
「Select XHTML Template」ページ(クリックして拡大)

テンプレートの定義で使用する ui:insert タグを使用するためには、 template.xhtml にネームスペースとして 「xmlns:ui="http://java.sun.com/jsf/facelets"」 を追加します。
template.xhtml のソースは次のようになります。

template.xhtml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><!-- a. ページごとに定義するページ・タイトル -->
<title>
<ui:insert name="title">JFS Template</ui:insert>
</title>
</head>
<body><!-- b. 全ページで共通のページ・ヘッダー -->
<div id="header" style="background-color:#F00; color:#FFF">
<h1>数字当てゲーム</h1>
</div><!-- c. 各ページで異なるコンテンツを表示する領域 -->
<ui:insert name="content">ページごとのコンテンツ</ui:insert>
</body></html>

開始ページの作成

図5: 開始ページ
図5: 開始ページ(クリックして拡大)
ここでは、開始ページ(index.xhtml)を作成します。
開始ページには、先ほど作成したテンプレート(template.xhtml)を適用します。
ユーザーは、このページに名前を入力することでゲームを開始します。
このページには次のような UI コンポーネントと Facelets タグを配置します。

  1. 適用するテンプレートを指定 (ui:composition タグ)
  2. ページごとに固有の設定(title/content)を指定 (ui:define タグ)
  3. HTTP ポスト・リクエストを送信するための form タグ (h:form タグ)
  4. 名前を入力するためのテキスト・フィールド (h:inputText タグ)
  5. 入力された名前をサーバーに送信し、ゲームを開始するためのボタン (h:commandButton タグ)

今回は、プロジェクト作成時に生成された index.xhtml ファイルを次のように編集します。

index.xhtml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets">
<!-- a. 適用するテンプレートの指定 -->
<ui:composition template="template.xhtml"><!-- b. ページ固有の設定(title)を指定 -->
<ui:define name="title">ようこそ</ui:define><!-- b. ページ固有の設定(content)を指定 -->
<ui:define name="content"><!-- c. HTTPポスト・リクエストを送信するためのformタグ -->
<h:form>
<div> あなたのお名前は?<!-- d. 名前を入力するためのテキスト・フィールド -->
<h:inputText size="12"/><!-- e. 入力された名前をサーバーに送信し、ゲームを開始するためのボタン -->
<h:commandButton value="開始"/>
</div>
</h:form>
</ui:define>
</ui:composition>
</html>

ゲーム・ページの作成

図6: ゲーム・ページ
図6: ゲーム・ページ(クリックして拡大)
次にゲームを遊ぶためのページ(game.xhtml)を作成します。
開始ページと同様に、先ほど作成したテンプレート(template.xhtml)を適用します。
このページには次のようなUIコンポーネントと Facelets タグを配置します。

  1. 適用するテンプレートを指定
    ui:composition タグ)
  2. ページごとに固有の設定(title/content)を指定
    ui:define タグ)
  3. HTTP ポスト・リクエストを送信するための form タグ
    h:form タグ)
  4. ユーザーへのメッセージ
    h:outputFormat タグ/f:param タグ)
  5. 数字を入力するためのテキスト・フィールド
    h:inputText タグ)
  6. サーバーに回答を送信するためのボタン
    h:commandButton タグ)
  7. ゲームをやり直す(開始ページに戻る)ためのボタン
    h:commandButton タグ)

template.xhtml を作成した時と同様の手順で、game.xhtml を作成します。game.xhtml のソースは次のとおりです。

game.xhtml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<!-- a. 適用するテンプレートの指定 -->
<ui:composition template="template.xhtml"><!-- b. ページ固有の設定(title)を指定 -->
<ui:define name="title">数字当てゲーム</ui:define><!-- b. ページ固有の設定(content)を指定 -->
<ui:define name="content"><!-- c. HTTPポスト・リクエストを送信するためのformタグ -->
<h:form>
<div><!-- d. ユーザーへのメッセージ -->
<h:outputFormat value="{0}さん、{1}">
<f:param value="ユーザー名"/><!-- {0}に入る値 -->
<f:param value="3つの異なる数字を入力してください。"/><!-- {1}に入る値-->
</h:outputFormat><!-- 実行時「ユーザー名さん、3つの異なる数字を入力してください。」と表示される-->
</div>
<div><!-- e. 数字を入力するためのテキスト・フィールド -->
<h:inputText size="2" maxlength="1"/>
<h:inputText size="2" maxlength="1"/>
<h:inputText size="2" maxlength="1"/><!-- f. サーバーに回答を送信するためのボタン -->
<h:commandButton value="回答"/><!-- g. ゲームをやり直すためのボタン -->
<h:commandButton value="やり直す"/>
</div>
<h2>回答履歴</h2><!-- 次回ここに回答履歴のテーブルを追加 -->
</h:form>
</ui:define>
</ui:composition>
</html>

データの受け渡しの設定

JSF では、テキスト・フィールドなどに入力されたデータの受け渡しに JavaBeans を使用します。
それらの JavaBeans は、インスタンスの有効期間をスコープとして指定する必要があります。
JavaBeans のインスタンスのライフサイクルは、スコープの設定に応じて Web コンテナによって管理されることから、JSF ではマネージド Bean と呼ばれます。
JSF 2.0 では、マネージド Bean のスコープとして次の6種類を設定できます。


  • application: Web アプリケーションが起動してから終了するまでの間
  • session: HTTP セッションが有効な間
  • request: HTTP リクエストを受けてからレスポンスを返すまでの間
  • view: ページがロードされてから他のページにナビゲートするまでの間 【JSF 2.0新機能】
  • flash: ページが別のページにナビゲートする間 【JSF 2.0新機能】
  • none: スコープには属さない(他のマネージド Bean から参照されるマネージド Bean などに使用)
図7: 「New Java Class」ウィンドウ
図7: 「New Java Class」ウィンドウ
(クリックして拡大)
今回は、ユーザー情報を格納するためのマネージド Bean (jsfsample.UserBean クラス)を作成します。
このマネージド Bean は name プロパティを持ち、ユーザーの名前を格納します。
ユーザーの名前は2つの画面にまたがって保持したいので、スコープは session に設定します。
プロジェクトにマネージド Bean を追加するために、Eclipse の「Project Explorer」ペインで「jsfsample」→「Java Resources」を右クリックし、「New」→「Java Class」を選択します。
「New Java Class」ウィンドウが表示されたら、「Package」に「jsfsample」、「Name」に「UserBean」と入力し、「Interaces」に「java.io.Serializable」を追加してから「Finish」ボタンをクリックします。
JSF 1.2 までは、マネージド Bean は Java クラス名やスコープなどの情報をfaces-config.xmlに記述する必要がありましたが、JSF 2.0 からはアノテーションを使用できるようになりました。
jsfsample.UserBean クラスのソースは次のとおりです。
UserBean.java
package jsfsample;
import java.io.Serializable;
@javax.faces.bean.ManagedBean // マネージドBeanであることを宣言するアノテーション
@javax.faces.bean.SessionScoped // このマネージドBeanがsessionスコープであることを表すアノテーション
public class UserBean implements Serializable {
private String name; // ユーザーの名前を格納するプロパティ
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

JSF では、マネージド Bean に定義されたプロパティやアプリケーション・メソッドにアクセスするために、EL 式 (Expression Language) を使用します。
EL 式は JSP 2.0 で導入された技術なので、使用したことがある開発者の方も多いと思います。
JSP と JSF は以前、それぞれ独自の EL 式の仕様を策定していましたが、 Java EE 5 以降は、JSP/JSF から独立した仕様として策定されています。
マネージド Bean のプロパティにアクセスするための EL 式は、次のような形式になります。

#{マネージドBean名.プロパティ名}

今回のようにマネージド Bean をアノテーションで定義した場合、「マネージドBean名」は、クラス名の最初の文字を小文字に置き換えたものです。
今回使用するマネージド Bean のクラス名は UserBean なので、マネージド Bean 名は「userBean」になります。
なお、マネージド Bean 名は、明示的に指定することもできます。
マネージド Bean 名を明示的に指定するには、アノテーション @ManagedBeanname 属性を使用します。

@ManagedBean(name="mybean")

index.xhtml のテキスト・フィールド(h:inputTextタグ)に入力されたデータを UserBeanname プロパティに格納するためには、次のように h:inputText タグの value 属性に EL 式を追加します。

index.xhtml 変更前
<h:inputText size="12"/>
index.xhtml 変更後
<h:inputText size="12" value="#{userBean.name}"/>

index.xhtml で入力された名前(UserBeanname プロパティの値)を game.xhtml に表示させるためには、次の部分を変更します。

game.xhtml 変更前
<f:param value="ユーザー名"/>
game.xhtml変更後
<f:param value="#{userBean.name}"/>

ページ・ナビゲーションの設定

JSF 1.2 では、あるページから別のページにナビゲートさせるためには、 faces-config.xml にナビゲーション・ルールを定義する必要がありあました。

JSF 1.2 のナビゲーション・ルールの定義例
<navigation-rule>
<from-view-id>/index.jsp</from-view-id>
<navigation-case>
<from-outcome>start</from-outcome>
<to-view-id>/game.jsp</to-view-id>
</navigation-case>
</navigation-rule>

上の例のようにナビゲーション・ルールが定義されている場合、 index.jsp に配置された h:commandButton タグ(ボタン)や h:commandLink タグ(リンク)の action 属性にナビゲーション・ルールで定義された from-outcome 要素の値「start」を指定することで、ボタン/リンクがクリックされた時に game.jsp にナビゲートされます。

JSF 2.0 からは、暗黙的ナビゲーションが使用できます。
暗黙的ナビゲーションでは、 action 属性にナビゲート先の Facelets ページの名前(拡張子は省略可能)を指定します。
faces-config.xml にナビゲーション・ルール を記述する必要はありません。
今回のアプリケーションでは、 index.xhtml に定義した「開始」ボタンをクリックしたら game.xhtml にナビゲーションさせるので、次のように h:commandButton タグの action 属性の値を「game」と指定します。

index.xhtml 変更前
<h:commandButton value="開始"/>
index.xhtml 変更後
<h:commandButton value="開始" action="game"/>

game.xhtml に定義した「やり直し」ボタンをクリックした時に開始ページ(index.xhtml)にナビゲートする場合は、同様に h:commandButton タグの action 属性に「index」を指定します。

game.xhtml 変更前
<h:commandButton value="やり直す" />
game.xhtml 変更後
<h:commandButton value="やり直す" action="index"/>

作成したアプリケーションを実行してみましょう。
「Project Explorer」ペインで「jsfsample」→「WebContent」→「index.xhtml」を右クリックし、「Run as」→「Run on Server」を選択します。
「Run on Server」ウィンドウが表示されたら、実行に使用するWebLogicドメインを選択し、「Finish」ボタンをクリックします
(このとき、「Always use this server when running this project」をチェックしておくと、次回からは「Run on Server」ウィンドウがスキップされて便利です)。

エディタ・ウィンドウに開始ページが表示されたら、名前を入力して「開始」ボタンをクリックします(図8)。
ゲーム・ページには、開始ページに入力した名前が表示されます。ゲーム・ページの「やり直し」ボタンをクリックしたら、開始ページに戻ります(図9)。






図8: 実行画面: 開始ページ
図8: 実行画面: 開始ページ
(クリックして拡大)
図9: 実行画面: ゲーム・ページ
図9: 実行画面: ゲーム・ページ
(クリックして拡大)

まとめ

今回は JSF の特長について簡単に説明し、JSF ページを作成して画面遷移の設定を行いました。
作成したアプリケーションでは次の JSF 2.0 の新機能を使用しました。


  • Facelets
  • ページ・テンプレート
  • アノテーションによるマネージドBeanの定義
  • 暗黙的ナビゲーション

次回は、ユーザーが入力したデータを変換するコンバータや検証するためのバリデータを設定したり、アプリケーション・ロジックを実装したりする予定です。
また、Ajax テクノロジを使用した部分ページ・レンダリングの機能を使用します。

Be the first to comment

Comments ( 0 )
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.