Teedaのサンプルアプリを読んでみる(1)
ではログイン画面から。URLはhttp://localhost:8080/todo-manage/view/todo/login.html。/todo-mangeはContext path(WebAP名称)で、残り/view/todo/login.htmlがファイル名か。そうなるとlogin.htmlに対応するPageクラスはweb.todo.LoginPageとなるはず。実際にtodo-manageプロジェクトの中を見ていくとjp.co.gihyo.javaexpert.todo.web.todo.LoginPageというのがある。Churaの規約を考えるとこのサンプルアプリのルートパッケージはjp.co.gihyo.javaexpert.todoなんだろう。
login.htmlにはuser, pass, doLoginという3つのidがある。それぞれtext, password, submitの名前。前2つについては同名のプロパティがLoginPage.javaにあり、doLoginと同じ名前のメソッドも定義されているのがわかる。これらの関連付けはTeedaが自動でやってくれるわけだ。
login.htmlを見て行くと最初に気がつくのがformタグが妙にシンプルということ。
<form id="loginForm">
ふつーここにはmethodでGET/POSTを指定したり、actionでsubmit先を書いておくもの。それが無い。じゃどこで指定するの?って、これもTeedaが自動でやるのね。ブラウザに表示されたlogin.htmlのソースをみるとちゃんと設定されている。
<form id="loginForm" name="loginForm" method="post" enctype="application/x-www-form-urlencoded" action="/todo-manage/view/todo/login.html">
ただactionはサーブレット名とかPageクラス名じゃなくて、このhtmlへのパス名になっている。これはJSFの仕様なのか、それともMyFaces独自のものなのかは不明。ただweb.xmlには
<servlet> <servlet-name>facesServlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>2</load-on-startup> </servlet> <servlet-mapping> <servlet-name>facesServlet</servlet-name> <url-pattern>*.html</url-pattern> </servlet-mapping>
と書かれているので、FacesServletがsubmitを受け取ってライフサイクルが始まるんでしょう。
<span id="messages" class="err"/>
のmessagesはid属性を持ったコンポーネントに関係しないエラーを表示するもの。errはjavaのクラス名ではなくCSSのもの。とうぜんエラーがなければレンダリングされない。
そしてユーザ名を入力するtextフィールド。ちょっと改行して見やすくすると次のような感じ。
<td class="v"> <input type="text" id="user" maxlength="32" style="width: 100px;"/><label id="ユーザ名"/> </td> <td> <span id="userMessage" class="err"/> </td>
最初のinputタグはいいわな。このid属性をキーにしてTeedaがLoginPageのプロパティuserとの間で自動的にやりとりしてくれる。わからないのがその次のlabel。Teeda Extensionのドキュメントによると「外部ファイルから文字列を出力するコンポーネント」とあるが、この「ユーザ名」に該当するものはlabel_ja.propertiesで定義されていない。レンダリングされたhtmlをみると、
<label id="ユーザ名"></label>
のままなので、もしかしてHTMLのlabelタグなのかもしれないが、textフィールドと関連付けする情報は書かれていない。アクセシビリティのためか?。
userMessageはエラーメッセージ用。id名+"Message"となっていて、このid名のコンポーネントで発生したバリデーションエラーやコンバート時の変換エラーのメッセージを表示する。
次のpassも同様。submitはidにdoLoginがなので、クリックされるとLoginPage.doLogin()が実行されることになる。html側はこんな感じかな。