Clickを使ってみる
$formとか$tableで表示できるってところに誘われてClickを見てたら、使いたくなってきたのでちょっと勉強。
まず、EclipseでTomcatプロジェクトを作ったあと、click-blank.warを解凍して上書き。
これでClickの環境が完成!!
何をすればいいのかよくわからないので、http://click.sourceforge.net/をみて勉強。
まず、自動的にmappingするため(?)、click.xmlのpagesタグを変更する必要があるみたい。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <click-app> <pages package="sample.page" automapping="true"> <!-- <page path="index.htm" classname="Home"/> --> </pages> <headers> <header name="Pragma" value="no-cache"/> <header name="Cache-Control" value="no-store, no-cache, must-revalidate, post-check=0, pre-check=0"/> <header name="Expires" value="1" type="Date"/> </headers> <mode value="development"/> </click-app>
英語は全然ダメだから、この辺でみるのをやめる。実践あるのみ。
でも何からはじめればよいかわからないから、IntroductionのLoginを真似てみる。
まずは必要となるDTOから
package sample.dto; public class UserDto { private String username; private String password; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
次は、ちょっとだけ変更したPageクラス
package sample.page; import net.sf.click.Page; import net.sf.click.control.Form; import net.sf.click.control.PasswordField; import net.sf.click.control.Submit; import net.sf.click.control.TextField; import sample.dto.UserDto; import sample.service.LoginService; import sample.service.impl.LoginServiceImpl; public class Login extends Page { private Form form = new Form("form"); private LoginService login; public Login() { form.add(new TextField("username", true)); form.add(new PasswordField("password", true)); form.add(new Submit("ok", " OK ", this, "onOkClicked")); addControl(form); login = new LoginServiceImpl(); } public boolean onOkClicked() { if (form.isValid()) { UserDto user = new UserDto(); form.copyTo(user); if (login.execute(user)) { getContext().setSessionAttribute("user", user); setRedirect("secure.htm"); } else { form.setError(getMessage("authentication-error")); } } return true; } }
そして実際のログインできるかを判断するLoginServiceのインターフェースと実装
package sample.service; import sample.dto.UserDto; public interface LoginService { public boolean execute(UserDto dto); }
package sample.service.impl; import sample.dto.UserDto; import sample.service.LoginService; public class LoginServiceImpl implements LoginService { public boolean execute(UserDto dto) { return dto.getUsername().equals(dto.getPassword()); } }
入力されたusernameとpasswordがいっしょだったらOKで違ってたらNGという単純な作り。
そして、login.htmと
<html> <body> <h2>Login</h2> $form </body> </html>
結果を表示するsecure.htm
<html> <body> <h2>Hello $session.user.username</h2> </body> </html>
そしてTomcatを実行して、http://localhost:8080/click-sample/login.htmでログイン画面が表示できたー。
でも、、、ちょっと触ってみるといろいろと問題が。。。
- まず何もせずOKボタンをクリックするとエラーメッセージが表示されるんだけど????となってる
- ログインエラーになるように異なるUsernameとPasswordを入力するとError Pageが表示される
- ログインするために同じUsernameとPasswordを入力するとPage Not Foundとなる
一番下のは簡単そうだなー。もしかして対応するPageクラスがないからかも。
ためしに下のような空のPageクラスを作って
package sample.page; import net.sf.click.Page; public class Secure extends Page { }
再度ためしたらうまくいった。1つ解決残り2つ。
ログインエラーのも簡単になおりそう。
おぉ!!Error Pageのリンクをクリックしたら、エラーの詳細がソースつきで表示される。この機能は重宝しそう。
エラーの原因はリソースファイルにauthentication-errorが定義されていないからみたい。ってことで、Loginクラスと同じ場所にLogin.propertiesを
authentication-error=authentication error.
として作成。うむうむうまくいった。getMessage()を利用する場合はPageクラスごとにpropertiesを用意するってことかな(はやとちりかも)。あと1つ。
????となるのはやっぱり文字コードを指定してないからだろなー。でもVelocityも今まで使ったことないしよくわからない。。。
そういえば、click.xmlにheader情報を定義しているところがあったな。。。
ためしにclick.xmlのheadersタグに下のを追加してみたら、
<header name="Content-Type" value="text/html; charset=UTF-8"/>
うまくいった。
でも、ここで定義してもいいのかなー。ダウンロードがどうなるのか心配だけど、そのときに悩むことにしよう。とりあえずはこれでOKと。
これで最初に思いついた問題はすべて解決したけど、
よく考えたら(よく考えなくても)日本語を入力したら文字が化けるかも。。。
やっぱり化けた。
Filterを追加すべきかなー。click.dtdをみるとclick-appにcharset属性がある。click.xmlで定義してみる。
おー、うまくいった。
もしかしてheaderで定義したContent-Typeは不要かも。。。はずして実行してみたら、エラーメッセージがきちんと表示された!!
結局click.xmlのclick-app charsetを定義すればよいってことなのかな。
はやとちりと勘違いはまだたくさんありそうだけど、最初の第一歩としては良い印象。
初めてStrutsを利用したときよりかは楽に入れた感じがする。6年間の成長か、それともTagLibとVelocityの差か、、、
でも、本当の良さはもっと使わないとわからないなー。