このアーカイブは同期化されません。 mixi の日記が更新されても、このアーカイブには反映されません。
昨日のようにリクエスト属性を使い、
メッセージを JSP に渡す方法でも構わないのだが、
これでは規模が大きくなってくると管理が難しくなる。
Struts には、フォームの検証を行い、
その検証結果を元にメッセージを作成し
それを JSP に引き渡す仕組みを持っている。
今度は、Struts の持つ検証機能を使って、
入力の検証やメッセージ表示を行ってみよう。
まずは、検証の部分からやっていこう。
ActionForm には、自身の内容を検証するための、
validate メソッドがある。
ActionErrors validate(
ActionMapping mapping,
HttpServletRequest request);
昨日まででは、Model に検証コードを書いていたが、
このメソッドに検証コードを写すことで、
Model を本来の処理だけに集中させることができる。
=========== LoginForm#validate ===========
public ActionErrors validate(ActionMapping mapping,
HttpServletRequest request) {
ActionErrors errors = new ActionErrors();
if (user == null || user.length() == 0) {
ActionMessage m =
new ActionMessage(
"ユーザ名を入力してください。", false);
errors.add("user", m);
}
if (password == null || password.length() == 0) {
ActionMessage m =
new ActionMessage(
"パスワードを入力してください。", false);
errors.add("password", m);
}
if (!errors.isEmpty()) return errors;
// ユーザ名は guest 限定とする
// パスワードは hogehoge 限定とする
if (!"guest".equals(user)
|| !"hogehoge".equals(password)) {
ActionMessage m =
new ActionMessage(
"ユーザ名またはパスワードが違います。",
false);
errors.add(null, m);
}
return errors;
}
=========== end of LoginForm#validate ===========
validate では、フォーム自身で内容の検証を行う。
戻り値は、ActionErrors クラス型である。
ActionErrors は検証で発生したエラーを保持するクラスで、
ある 1 つのエラーを示す ActionMessage インスタンスを、
複数同時に格納することができる。
フォームの内容に問題がなかった場合は、
null または ActionMessage を 1 つも持たない、
空の ActionErrors インスタンスを返せばよい。
上記処理では、昨日よりも 1 歩進め、
ユーザ名やパスワードが空の場合もエラーとしてみた。
エラーメッセージは、ActionMessage インスタンスで表す。
2 番目の引数に false を指定すると、
メッセージを直接格納することができる。
本来 ActionMessage では、直接メッセージを指定せず、
ResourceBundle から文字列を取得するのが好ましいのだが、
まずは使い方ということで、直接指定してみた。
さて、ActionMessage を作成したら、
ActionErrors の add メソッドを呼び出して、
ActionErrors にメッセージを追加するのだが、
add メソッドは、ActionMessage の他に、
もう 1 つ文字列の property 引数を取る。
void add(String property, ActionMessage message);
ActionErrors の内部では、ActionMessage を
幾つかのグループに分類することができる。
add メソッドの第 1 引数は、グループの名前だ。
一般的には、エラー(ActionMessage)を、
それが発生した原因であるプロパティに関連付けるため、
グループ名として、プロパティ名を指定する。
例えば、ユーザ名の入力を促すエラーは、
そのプロパティ名である「user」グループへ、
パスワードの入力を促すエラーは、
そのプロパティ名である「password」グループへ、
そしれ、認証の失敗を示すエラーは、
フィールドを特定できないので、null のグループとした。
これで、検証用のコードはフォームに移動したため、
LoginAction の方では検証コードを消すことができる。
=========== LoginAction#execute ===========
public ActionForward execute(ActionMapping mapping,
ActionForm form, HttpServletRequest request,
HttpServletResponse response) throws Exception {
// パラメータを取得
LoginForm f = (LoginForm)form;
// ログイン成功!
// 「次回から入力を省略」にチェックがあれば
if (f.isPersistent()) {
// TODO: Cookie 等に情報を保存
}
// ログイン情報をセッションに保存
request.getSession().setAttribute("user", f.getUser());
return mapping.findForward(Forwards.SUCCESS_KEY);
}
=========== end of LoginAction#execute ===========
これで Model から検証処理を切り離すことができた。
少し保守性が増したと考えることができる。