JSF (JavaServer Faces) 2.0 の詳細について
日本オラクル Fusion Middleware 製品事業統括本部
寺田 佳央 (http://yoshio3.com)
2 | © 2011 Oracle Corporation – All rights reserved.
以下の事項は、弊社の一般的な製品の方向性に関する概要を説明するものです。
また、情報提供を唯一の目的とするものであり、いかなる契約にも組み込むことは
できません。以下の事項は、マテリアルやコード、機能を提供することをコミットメン
ト(確約)するものではないため、購買決定を行う際の判断材料になさらないで下さ
い。オラクル製品に関して記載されている機能の開発、リリースおよび時期につい
ては、弊社の裁量により決定されます。
Oracleは、米国オラクルコーポレーション及びその子会社、関連会社の米国及びその他の国における登録商標です。 文中の社名、商品名等は各社の商標または登録商標である場合があります。デモ:JSFサンプルアプリケーションの構成
DB
Facelets (xhtml)CDI
EJB クライアント Web アプリケーション Web コンテナ4 | © 2011 Oracle Corporation – All rights reserved.
JSF 2.0 (JPA+EJB+CDI+JSF+Ajax) デモ
6 | © 2011 Oracle Corporation – All rights reserved.
JavaServer Faces
JSFフレームワークと開発の概要
DB
Web
サービス
プレゼン テーション • アプリケーションロジック • コンバート (変換) • バリデーション (検証) • ナビゲーション (画面遷 移) • イベント処理 ビジネスロジック クライアント Web アプリケーション Web コンテナJSF における MVC
ビュー
(XHTML)コントローラ
(Faces Servlet)モデル
(マネージド Bean)操作・
リダイレクト
生成・管理
アクセス
HTTP
リクエスト
HTTP
レスポンス
8 | © 2011 Oracle Corporation – All rights reserved. コンバータ ブラウザ HTML JavaScript CSS バリデータ
JSF の内部アーキテクチャ
レ
ン
ダ
ラ
XUL JSP XHTML faces-config.xml (省略可能)Faces
Servlet
(コントローラ) マネージド Bean コンポーネント コンポーネント HTTP リクエスト HTTP レスポンスWebページ作成者
(デザイナー)
アプリケーション
開発者
コンポーネント開発者
JSF 開発者の役割(役割毎に疎で開発可能)
DB BackEnd 処理10 | © 2011 Oracle Corporation – All rights reserved.
Webページ作成者
(デザイナー)
アプリケーション
開発者
コンポーネント開発者
Web ページ作成者 (プレゼンテーション)
DB BackEnd 処理Web ページの基本
テキストフィールド
ラジオボタン
コンボボックス
テキストフィールド
ボタン
12 | © 2011 Oracle Corporation – All rights reserved.
HTML タグ
JSF タグ
<INPUT TYPE=“TEXT” value=“”> <h:inputText id="username" value=""/>
HTMLと対応するJSFタグ
HTML タグ
JSF タグ
<input type=“radio” name=“sex” value=“1”> 男性
<input type=“radio” name=“sex” value=“2”> 女性
<h:selectOneRadio id=”sex” value="sex">
<f:selectItem itemValue="1" itemLabel="男性" /> <f:selectItem itemValue="2" itemLabel="女性" /> </h:selectOneRadio>
<h:inputText>
タグ
<h:selectOneRadio>
タグ
テキストフィールド
HTML タグ
JSF タグ
<select size="1"> <option value=”1">北海道</option> <option value=”2">青森</option> <option value=”3">岩手</option> … </select> <h:selectOneMenu><f:selectItem itemValue="1" itemLabel="北海道" /> <f:selectItem itemValue="2" itemLabel="青森" /> <f:selectItem itemValue="3" itemLabel="岩手" /> …
</h:selectOneMenu>
HTMLと対応するJSFタグ
HTML タグ
JSF タグ
<input type="submit" value="確認画面へ進む" /> <h:commandButton value="確認画面へ進む" />
<h:selectOneMenu>
タグ
<h:commandButton>
タグ
コンボボックス
14 | © 2011 Oracle Corporation – All rights reserved.
http://javaserverfaces.java.net/nonav/docs/2.0/pdldocs/facelets/
HTML 4.0 & DHTML 属性利用可
onblur
onchange
onclick
ondblclick
onfocus
on
key
dow
n
onkeypress
o
n
mo
u
se
mo
ve
onkeyup
onload
onmousedown
onfocus
onmouseout
onmouseup
on
mou
seo
ver
on
rese
t
onselect
onsubmit
onunload
accesskey
accept
acce
ptch
arse
t
alt
border
charset
coords
dir
disabled
hreflang lang
maxlength
readonly
rel
rev
rows
shape
size
style
styleClass
tabindex
target
title
type
width
16 | © 2011 Oracle Corporation – All rights reserved.
スタイルシートの適用
<HTML>
<h:head>
<h:outputStylesheet"
library="css"
name="commonpage.css”
/>
</h:head>
<h:body>
……(省略)
<h:inputText
class="intext"
id="username" value=""/>
※ 全外部リソースは /resources ディレクトリ配下に配置
libraryで指定した css/ よりファイルを取得
.intext { width: 300px; border: solid 1px #000099; background-color: #9999ff; }
JavaScript の読み込み(h:outputScript)
<h:head> <h:outputScript library="javascript" name="checkPassword.js"/> </h:head> <h:body> <h:form> ログイン名: <h:inputText/> パスワード: <h:inputSecret id="password"/> パスワード(確認): <h:inputSecret id="passwordConfirm"/> <h:commandButton type="button" value="Submit Form" onclick="checkPassword(this.form)"/> </h:form> </h:body> function checkPassword(form) { var password = form[form.id +":password"].value; var passwordConfirm = form[form.id + ":passwordConfirm"].value; if (password == passwordConfirm) form.submit(); else alert(” パスワードと確認用パスワードの内容が違います” ); }
JavaScriptのコード
JSF (Facelets) のコード
/resources/javascript/checkPassword.js18 | © 2011 Oracle Corporation – All rights reserved.
表示メッセージの国際化対応
ロケール:ja_JP
ロケール:en_US
<h:outputText value="#{msgs.userName1}"/>
表示用の文字列をプロパティより取得
properties ファイルの作成と利用方法
<h:outputText value="#{msgs.userName1}"/>
<faces-config … <application> <resource-bundle> <base-name> jp.co.oracle.msgs.msgproperties </base-name> <var>msgs</var> </resource-bundle> </application> </faces-config> faces-config.xml
/WEB-INF/classes
配下に作成
userName1=名前userName1=Name _en_US.properties _ja_JP.properties
20 | © 2011 Oracle Corporation – All rights reserved. 1 ヘッダ部作成 2 左 ペ イ ン 作 成 4 フッダ部作成 3 右 ペ イ ン 作 成 共通部分の作成 5 テンプレート作 成 テンプレートの作成 コ ン テ ン ツ 各種ページの作成 コ ン テ ン ツ コ ン テ ン ツ コ ン テ ン ツ コ ン テ ン ツ コ ン テ ン ツ ご参考: http://yoshio3.com/2011/01/14/jsf20-new-with-facelets-template/
強力なテンプレート機能
デザイナーと開発者の共同作業が可能に
(jsfc=“”)
•
デザイナーはテキスト&ブラウザで確認
•
プログラマーはJSP&Webコンテナで確認
•
プログラム後のデザイン修正は困難
•
デザイナーはテキスト&ブラウザで確認
•
プログラマーはXHTMLに要素を挿入
• 同一ファイルの為デザイン修正も容易
デザイナー (HTML) プログラマー (JSP)コード変換
が必要
今までの開発スタイル デザイナー プログラマー (XHTML)同一ファイルを参照編集可能
JSF 2.0 の開発スタイル22 | © 2011 Oracle Corporation – All rights reserved.
XHTMLに対する JSF 要素の埋め込み (jsfc=“”)
<BODY> <FORM>
<input type="submit" value="OK"/> </FORM>
</BODY>
<BODY
>
<FORM >
<input type=“submit“ value="OK“
/>
</FORM>
</BODY>
※ブラウザは理解できない要素を無視するためブラウザで直接確認可能 デザイナー プログラマーjsfc="h:body”
jsfc="h:form“
jsfc="h:commandButton“
class="button1" action="#{action.button1Action()}“
※ <h:body> , <h:form> 等 JSF タグと同一タグを指定
Webページ作成者
(デザイナー)
アプリケーション
開発者
コンポーネント開発者
JSF 利用者の役割
DB BackEnd 処理24 | © 2011 Oracle Corporation – All rights reserved. View の復元 リクエスト値の 適用 入力値の検証 レスポンスの レンダリング App ロジックの 呼び出し モデル値の 更新 イベン ト 処理 イベン ト 処理 イベン ト 処理 イベン ト 処理
JSFのリクエスト処理のライフサイクル
リクエスト値の 適用 入力値の検証 レスポンスの レンダリング App ロジックの 呼び出し モデル値の 更新 イベン ト 処理 イベン ト 処理 イベン ト 処理 イベン ト 処理
JSFのリクエスト処理のライフサイクル
View の復元26 | © 2011 Oracle Corporation – All rights reserved. <HTML> <h:head> <title>タイトル</title> </h:head> <h:body> <h:form> <h:inputText/> <h:commandButton/> </h:form> </h:body> </HTML>
XHTML (Facelets)
UIComponent ツリー
View の復元 (UIコンポーネント・ツリーの作成・復元)
デコード
入力値の検証 レスポンスの レンダリング App ロジックの 呼び出し モデル値の 更新 イベン ト 処理 イベン ト 処理 イベン ト 処理 イベン ト 処理
JSFのリクエスト処理のライフサイクル
View の復元 リクエスト値の 適用28 | © 2011 Oracle Corporation – All rights reserved.
リクエスト値の適用
<h:inputText value=“#{someData}”/> <HtmlInputText disabled="false" id="username" immediate="false" inView="true" localValueSet="true" maxlength="-2147483648" readonly="false" rendered="true" required="false" size="-2147483648" styleClass="intext" transient="false" valid="false" value="hogehoge” /> コンポーネントツリーリクエスト
値の適用
UIVewRoot# processDecodes()レスポンスの レンダリング App ロジックの 呼び出し モデル値の 更新 イベン ト 処理 イベン ト 処理 イベン ト 処理 イベン ト 処理
JSFのリクエスト処理のライフサイクル
View の復元 リクエスト値の 適用 入力値の検証30 | © 2011 Oracle Corporation – All rights reserved.
バリデーション (Bean Validation)
public class Customer implements Serializable { … (省略)
@NotNull
@Size(max = 40)
@Pattern(regexp = "[a-zA-Z0-9]+@[a-zA-Z0-9]+¥¥.[a-zA-Z0-9]+", message = "メールアドレスの書式が不正です")
private String email; }
<h:inputText class="intext" id="e-mail" value="#{person.mail}"/>
<h:message for="e-mail" style="color:red"/>
バリデーション ( JSFカスタム バリデータ)
@FacesValidator("jp.co.oracle.validate.EmailValidator")
public class EmailValidator implements Validator{ private static final String EMAIL_PATTERN =
"[a-zA-Z0-9]+@[a-zA-Z0-9]+¥¥.[a-zA-Z0-9]+"; private Pattern pattern;
private Matcher matcher; public EmailValidator(){
pattern = Pattern.compile(EMAIL_PATTERN); }
32 | © 2011 Oracle Corporation – All rights reserved.
バリデーション ( JSFカスタム バリデータ)
続き
@Override
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
matcher = pattern.matcher(value.toString()); if(!matcher.matches()){
FacesMessage msg =
new FacesMessage("E-mail validation failed.", "Invalid E-mail format.");
msg.setSeverity(FacesMessage.SEVERITY_ERROR); throw new ValidatorException(msg);
コンバージョン – 入力データの変換
<h:inputText id="cal" value="#{person.date}"
required=“true” requiredMessage=”日付を入力してください”
converterMessage="日付の書式が違います。例:12/26/2011">
<f:convertDateTime pattern="MM/dd/yyyy”/>
</h:inputText>
<h:message for="cal" style="color:red"/>
public class Person{
Date date;
}
34 | © 2011 Oracle Corporation – All rights reserved. 入力値の検証 レスポンスの レンダリング App ロジックの 呼び出し イベン ト 処理 イベン ト 処理 イベン ト 処理 イベン ト 処理
JSFのリクエスト処理のライフサイクル
View の復元 リクエスト値の 適用 モデル値の 更新Value バインディング (通常はコチラを使用)
@ManagedBean(name=“person”)//@Named(value=“person”)
public class Person implements
Serializable { private String name;
private String addressline1; private String addressline2; private String city;
private String phone; private String email;
} //別途 Setter,Getter メソッドを用意 <h:inputText class="intext" id="username" value="#{person.name}"/>
<h:inputText class="intext" id="e-mail" value="#{person.email}"/>
36 | © 2011 Oracle Corporation – All rights reserved.
Bean を ManagedBean と JPA Entity で共用可能
@ManagedBean(name=“person”)
public class Person implements
Serializable {
private String name;
private String addressline1; private String addressline2; private String city;
private String phone; private String email;
} //別途 Setter,Getter メソッドを用意
DB
PERSON
テーブル
@Entity @Table(name = "PERSON") @Id @GeneratedValue @Column(name = "PERSON_ID") private Integer personId;@ManagedBean(name=“person”) //@Named(value=“person”)
public class Person implements
Serializable { private HtmlInputText name;
private HtmlInputText addressline1; private HtmlInputText addressline2; private HtmlInputText city;
private HtmlInputText phone; private HtmlInputText email;
} //別途 Setter,Getter メソッドを用意
Component バインディング (ニーズに応じて使用)
<h:inputText class="intext" id="username” binding="#{person.name}"/> <h:inputText class="intext" id="e-mail" binding="#{person.email}"/>
38 | © 2011 Oracle Corporation – All rights reserved. 入力値の検証 レスポンスの レンダリング イベン ト 処理 イベン ト 処理 イベン ト 処理 イベン ト 処理
JSFのリクエスト処理のライフサイクル
View の復元 リクエスト値の 適用 モデル値の 更新 App ロジックの 呼び出し実際の処理の実装
action でボタンが押下された際のメソッドにバインディング
<h:commandButton value="DBへ登録”
action="#{customerManage.savePerson}”/>
XHTML 側でバックエンド処理にバインド
@ManagedBean(name =
"customerManage")
//@Named(value =“customerManage”)
@RequestScoped
public class CustomerManage {
public String savePerson()
{
//バックエンド処理の実装
return "success";
}
}
40 | © 2011 Oracle Corporation – All rights reserved.
画面遷移(ナビゲーション)
<navigation-rule>
<from-view-id>page1.xhtml</from-view-id>
<navigation-case>
<from-outcome>next</from-outcome>
<to-view-id>/page2.xhtml</to-view-id>
</navigation-case>
</navigation-rule>
JSF 1.2 までのナビゲーションの設定
ページ 1
ページ 2
ページ 3
ページ 4
画面遷移(JSF 2.0 暗黙のナビゲーション)
<h:commandButton
action="page2"
value="Submit" />
ボタンが押下された場合 page2.xhtml へ画面遷移
<h:commandButton
action="page2.xhtml"
value="Submit" />
<h:commandButton
action=“page2.jsf”
value=“Submit” />
42 | © 2011 Oracle Corporation – All rights reserved.
画面遷移(JSF 2.0 暗黙のナビゲーション)
<h:commandButton
action=“#{customerManage.savePerson}"
value="Submit" />
@ManagedBean(name ="customerManage") @RequestScopedpublic class CustomerManage {
public String savePerson() {
//何らかの処理
return ”page2“; // page2.xhtml へ遷移 }
}
メソッドの戻り値(String)が
画面遷移先のページを示す
リダイレクト(JSF 2.0 暗黙のナビゲーション)
<h:commandButton action="page2
?faces-redirect=true
"
value="Submit" />
?faces-redirect=true
を指定しリダイレクト操作
@ManagedBean(name ="customerManage") @RequestScoped
public class CustomerManage { public String savePerson() { //何らかの処理
return ”page2.xhtml?faces-redirect=true“; }
44 | © 2011 Oracle Corporation – All rights reserved.
ManagedBean
or
CDI
似たような事はできますが別物
それぞれ、できる事が違います!!
オブジェクトとして一括データ取得(ManagedBean のみ)
@ManagedBean(name=“person”)
public class Person implements
Serializable { private String name;
private String addressline1; private String addressline2; private String city;
private String phone; private String email;
} //別途 Setter,Getter メソッドを用意
@ManagedBean(name ="customerManage")
@RequestScoped
public class CustomerManage {
@ManagedProperty(
value = "#{person}") private Person person;
public void setPerson(Person person) { this.person = person;
}//ManagedProperty には Setter が必須
public String savePerson() {
myEjb.persist(person); //DBに保存 return "success";
} }
46 | © 2011 Oracle Corporation – All rights reserved. 入力値の検証 イベン ト 処理 イベン ト 処理 イベン ト 処理 イベン ト 処理
JSFのリクエスト処理のライフサイクル
View の復元 リクエスト値の 適用 モデル値の 更新 App ロジックの 呼び出し レスポンスの レンダリングUIComponent ツリーから
レンダリング
コンポーネントの状態保存
HTMLエンコード
HTML HTMLレスポンスのレンダリング
48 | © 2011 Oracle Corporation – All rights reserved.
Webページ作成者
(デザイナー)
アプリケーション
開発者
コンポーネント開発者
JSF 利用者の役割
DB BackEnd 処理50 | © 2011 Oracle Corporation – All rights reserved.