SeasarプロジェクトのJSF実装。S2コンテナによるDI、各種開発を簡単にする拡張機能などを搭載。
最大の特徴は、JSPではなくXHTMLをテンプレートとして使う事ができること。面倒なface-configを書かなくてよいこと。また、バッキングビーンの代わりにPageというJavaBeansを用いる。
Pageにインジェクションされるコンポーネントは基本的にRequest単位でインスタンス化されるようだ。
よってサーブレットのようにインスタンスフィールドを使っても他人のデータが表示されるようなことは無い。
Pageの状態管理は良く分からない。あとで調べる。
<input type="button" id="jumpHoge" /> <input type="button" id="jumpFuga_Hoge" />
上:同じサブアプリケーションのhoge.htmlへ移動、下:fugaサブアプリケーションのhoge.htmlへ移動
必須チェックをするにはPage側に
@Required private String hogeName
というノリでアノテーション付ける。エラーメッセージはHTMLに「id名+Message」なspanタグを付けると表示される。
<input type="text" id="hogeName" /><span id="hogeNameMessage" class="error" />
とやるとspanのところにエラーメッセージが表示される。しかし「値を入力してください(hogeName)」のようにエラーメッセージにプロパティ名が出るのでダサい。
input属性にtitleを付けると
<input type="text" id="hogeName" title="ほげ名称" /><span id="hogeNameMessage" class="error" />
エラーメッセージは「値を入力してください(ほげ名称)」になる。
それもダサい、独自のエラーメッセージを出したいというならば以下のように書く。 appMessage.propertiesに以下の記述(当然、2バイト文字はプロパティ用にエンコードする必要がある、EclipseのプラグインResourceBundleEditor等を使うと良い)
hogeName.required=ほげ名称を入力してください
アノテーションを修正
@Required(messageId="hogeName.required") private String hogeName
Teeda 1.0.10
selectOneRadioにはRequiredバリデーションが利かないのでラジオボタンが押されているかどうかは独自にチェックするしかない。ラジオボタンで選択されていなければプロパティがnullになる。
エラーメッセージは
facesContext.addMessage("formのId:inputのId", FacesMessageUtil.getMessage(facesContext, "appMessages.propertiesのキー", new Object[0]));
で設定できる。Actionには何故かFacesContextがDIされないので
FacesContext facesContext = FacesContext.getCurrentInstance();
で取得する。
Tigerアノテーションはフィールドにもゲッタセッタメソッド好きなものに付けられる。ただしPageクラスを継承したとき、親クラスにフィールド、ゲッタ、セッタがある場合は、フィールドに付けても有効にならない。ゲッタかセッタに付ける。
おそらくアノテーションを調べる時に親クラスのprivateフィールドまで見に行かないのだと思う。
フィールドがpublicでゲッタセッタ無しなら効くかもしれない…(要確認)
forEachのためにPage側には、
が必要。
// DTO public class Person { private Date birthDay; // Getter、Setterは脳内補完してください private String name; // Getter、Setterは脳内補完してください } // Page public class MemberListPage { // 繰り返し項目格納のItems private List<Person> personItems; // 繰り返すPersonの中身 private String name; private Date birthDay; }
MemberListPageのPersonの中身プロパティの型と名前は、繰り返しするPersonクラスのプロパティの型と名前に一致させる。クラスは完全一致、サブクラスとかでもダメ。
PageのプロパティはString等だけではなくJavaBeansでもいい。この場合は、toStringされた値が出力される。複数の値を組み立てて値を組み立てる必要がある場合に便利。
Pageクラスのgetterにアノテーションを付ける
@DateTimeConverter(pattern = "yyyy年MM月dd日") public Date getMyBirthDay() { return myBirthDay; }
Getterではなくフィールドでも良いっぽい。
数字は
@NumberConverter(pattern="#,###.#") private double hoge;
TeedaのselectOneMenu、selectManyCheckbox、selectOneRadioを動的出力するために、valueとlabelというプロパティを持つJavaBeansのリストを、hogeItemsというプロパティ名でPageに設定する。
JavaBeansには、javax.faces.model.SelectItemというクラスを使うことができる。これを使った場合、javax.faces.model.SelectItemGroupでラップするとoptgroupも出力することができる。
わざわざDTOを作るのがだるい、hogeエンティティをhogeItemsとして使いたいというならば、valueとlabelというプロパティをエンティティに作ってしまえばいい。プロパティidをvalue、プロパティnameをlabelとして使いたいならば…
public Integer getValue() { return this.id; } public Integer getLabel() { return this.name; }
といったメソッドをエンティティに追加してしまう。
<select id="hoge"></select>
まずTeeda Ajaxのライブラリを取り出す。teeda-ajaxのjarファイルにjsファイルが含まれているのでjarを解凍して取り出す(ホントか?)。言うまでもないがjarの正体はzip圧縮ファイル。
Smart Deployを使う場合は、Pageクラスにプレフィックスがajaxで始まるメソッドを用意する。Pageのサブアプリケーションがhoge、PageクラスがFugaPage、呼び出されるサーバ側のJavaメソッドがajaxExecuteの場合、JavaScript側は
Kumu.Ajax.executeTeedaAjax(hoge_fugaPage_ajaxExecute, [], Kumu.Ajax.RESPONSE_TYPE_JSON); // コールバック関数 function hoge_fugaPage_ajaxExecute(response) { // Ajaxコールバック処理 }
と書く。
Kumu.Ajax.executeTeedaAjaxの引数は…
Java側のajaxメソッドをアクションに記述する場合はfugaPageをfugaActionに
Kumu.Ajax.executeTeedaAjax(hoge_fugaAction_ajaxExecute, [], Kumu.Ajax.RESPONSE_TYPE_JSON); function hoge_fugaAction_ajaxExecute(response) { }