前々回と前回にわたり、slim3とVelocityのインストールをして、基本的なController、Model、Serviceの各クラスの作り方を書きました。
slim3では、1つのページ(URL)に1つのControllerクラスを作ります。
フレームワークにより、1つのサーブレットで沢山の機能を持ついわゆるマジックサーブレットにはならない事が強制されます。
しかもマッピングの為の設定ファイルを書かないで済むみます。
設定ファイルと言えばslim3というよりGAEの事ですが、スキーマレスでRDBMSの物理設計や論理設計をすっ飛ばして開発出来るのは非常に楽です。
一応元RDBMS屋な自分としては涙目な訳ですが、これも時代の流れと諦めてます。
mavenでJavaBeanからOracleとかのDDLを生成した時にも感動しましたが、ソレとは比較にならない位開発の負荷が激減します。
代わりにGAEでは機密性をどう担保するの?とかバックアップとらんでえーの?とかデータの一貫性大丈夫?とか運用フェーズでの苦労は増えそうな予感がします。
あとslim3では、URLが判ればソースコードの場所がすぐ判ります。
保守フェーズではコレは非常に重要なことです。
一度でも他人の作ったWEBアプリケーションを保守したヒトなら判るでしょう。
代償?として、slim3ではControllerのコードを沢山書く事になる訳で、1つ1つのControllerのコードをいかにスリムにするかが、生産性を落とさない為に重要になってきそうです。
その為には、slim3に既に用意されている機能をフル活用し、slim3の制約を受け入れ、自己流のコードを少なくするする方向で設計・開発する事が重要でしょう。
また、slim3をさわる方は、おそらく業務アプリケーションを請負で作っている方が主流なんだと思いますが、いわゆるWEB屋の現場では「ページ作るヒト」 = 「WEBデザイナ的なヒト」 という現場も結構あるんじゃないでしょうか。
「Controllerを作るヒト」 = 「perlやphpならちょっと書けるWEBデザイナ」位を想定して、手順化や規約作りをしておいた方がよさそうです。
まだチョットしか触ってませんが、slim3が感動的な位よさげなもので熱くなってしまいました。
前置きが長くなりましたが、今回はControllerを作りこんでいきます。
入会フォーム的なものを作る前提で書いています。
ControllerクラスでHTTPリクエストの引数を取得する
Controller で HTTPリクエストのパラメータ (GET、POSTの引数)は、親のControllerクラスのasString(), asShort(), asInteger(), asLong(), asFloat(), asDouble(), asBoolean(), asDate() and asKey()を使えば取得できます。
public class IndexController extends Controller { public Navigation run() throws Exception { String email = asString("email"); ....
VMファイル側でフォームの値を保持する
で、VMファイル(VTLを書いたTempleteファイル、index.vmとか)側で、普通は、フォームに一度入力した値を保持しときますよね。
slim3 には Struts で言う所の ActionForm に相当するクラスが無い様です。
JSPならサンプルが有るんですが、VTL用に方法を考えないといけません。
とりあえず、Requestパラメータは RequestHandler によってRequestのAttributeにコピーされているそうなので、こうしました。
<input type="text" name="email" value="$!request.getAttribute('email')" />
Controllerクラス と VTL でバリデーションチェックをする
slim3のControllerにはバリデーションチェックも用意されています。
これもslim3-demoを参考にしました。
public Navigation run() throws Exception { if (!validate()) { return forward("/path/to/failed.vm"); } return forward("/path/to/success.vm"); } protected boolean validate() { Validators v = new Validators(request); v.add(meta.email, v.required(), v.maxlength(256), v.minlength(6) , v.regexp("\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*([,;]\\s*\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*)*")); return v.validate(); }
うーん、簡単です。
詳しくは、org.slim3.controller.validator.Validators クラスのAPIを見て、との事です。
バリデーションチェックの結果をVMファイルで表示する
で、結果をView側で表示する訳ですが、JSPを使用する場合に、エラーメッセージを参照するのは簡単です。
${f:h(errors.email)}
で、VelocityのVTLではどーしたもんかなぁと小一時間悩みましたが、エラーメッセージはRequestスコープのAttribute(errors)にセットされているのでそれを使います。
#if($request.getAttribute("errors").email) <font color="red">$!request.getAttribute("errors").email</font> #end
Velocityのmacroにしようと挑戦しましたが、出来ませんでした。
余談ですがRequestスコープのAttribute(slim3.controller)にControllerもセットされる様です。
バリデーションエラーメッセージのプロパティ名を日本語化
さて、バリデーションチェックが便利になりましたが、表示されるエラーメッセージのプロパティ名がクラスのフィールド名になってしまいます。
先述の例では、こんな感じです。
emailは必須です。
ソースコードを読みあさる事数時間、しばし悩む。
あとになってしっかりドキュメントに書いている事に気がつきました。
ロケールによって属性名を変更したい場合は、label.
というエントリを /src/application[_locale].properties に定義して下さい。
src/application_ja.properties に書き込めばよいです。
書式はこうです。
label.email=メールアドレス
native2asciiする必要がありますので、実際にはこうなります。
label.email=\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9
エラーメッセージはこうなりました。
メールアドレスは必須です。
バリデーションエラーの場合 type=”text”のフォームの色を変える
slim3-demo を動かしてみると、エラー時にフォームの表示を工夫しています。
JSPの場合タグライブラリのerrorClassを使えば良いようです。
<input type="text" ${f:text("email")} class="${f:errorClass('email', 'err')}"/>
slim3-blankでは最初から、スタイルシート側 で inputタグのクラスがerrの場合の色指定をしています。
スタイルシートをいじれば色々と応用できそうですね。
VMファイルでこれを実現するのには、org.slim3.jsp.Functions の errorClassメソッドをパクってVelocityServlet側で同様の機能を実装しちゃいました。
<input type="text" name="email" class="$p.errorClass('email', 'err')" value="$!request.getAttribute('email')" />
今回、思ったほど進みませんでした。
次回は、更新系の処理を完成させたいです。