Jakarta Struts 1.1 の新機能、Validator を拡張する方法。『Jakartaプロジェクト徹底攻略 』と『マスタリング Jakarta Struts』の二冊を読んだけど、どちらにも書いていなかったので忘れないうちにメモしておく。
今回やりたかったのは、Validator でフォームの入力値に全角文字が含まれていないかをチェックするということ。入力の有無やメールアドレスの書式などのチェックを Validator で行ったので、方法を統一するために Validator を拡張して対応する。
Validator を拡張する際に関係するのは、
の4つ。FieldChecks クラスには Validator が基本で備えている required, email, range などのルールそれぞれに validateRequired(), validateEmail(), validateRange() とメソッドが定義されている。
FieldChecks を継承した EnhancedFieldChecks に半角文字列(かどうか)検査用 validateHankaku() を定義して拡張する。validator-rules.xml で、hankaku というキーに対して EnhancedFieldChecks#validateHankaku() が呼ばれるように設定し、validation.xml で、任意の入力フィールドに対して hankaku キーワードを指定すれば、その入力フィールドに半角チェックが起動する。
まず、EnhancedFieldChecks 。validateHankaku() と isHankaku() を定義。半角かどうかの判定は [JavaHouse-Brewers:18305] を参考に、半角文字列が 0x0020 〜 0x007E にマッピングされていることを利用した。実際には isHankaku() メソッドの中身だけロジックを書いて、あとの部分は FieldChecks の他のメソッドの内容をほぼコピペ。
package org.dyndns.naoya;
import java.text.CharacterIterator;
import java.text.StringCharacterIterator;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.validator.Field;
import org.apache.commons.validator.GenericValidator;
import org.apache.commons.validator.ValidatorAction;
import org.apache.commons.validator.ValidatorUtil;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.validator.FieldChecks;
import org.apache.struts.validator.Resources;
public class EnhancedFieldChecks extends FieldChecks {
public static boolean validateHankaku(
Object bean,
ValidatorAction va,
Field field,
ActionErrors errors,
HttpServletRequest request) {
String value = null;
if (isString(bean)) {
value = (String) bean;
} else {
value = ValidatorUtil.getValueAsString(bean, field.getProperty());
}
if (!GenericValidator.isBlankOrNull(value) && !isHankaku(value)) {
errors.add(
field.getKey(),
Resources.getActionError(request, va, field));
return false;
} else {
return true;
}
}
private static boolean isHankaku(String str) {
boolean state = true;
CharacterIterator iter = new StringCharacterIterator(str);
for (char c = iter.first();
c != CharacterIterator.DONE;
c = iter.next()) {
if (!(c > 0x0020 && c < 0x007F)) {
// 全角!
state = false;
break;
}
}
return state;
}
}
次に、validator-rules に hankaku ルールを追加する。classname に拡張したクラス、起動するメソッドの名前に半角チェック用メソッドを指定する。それから、チェックに失敗した際にエラーメッセージを出力するとして、そのエラーメッセージはリソースファイル内のどれに対応させるか、msg 属性で指定する。
<form-validation>
<global>
<validator name="hankaku"
classname="org.dyndns.naoya.EnhancedFieldChecks"
method="validateHankaku"
methodParams="java.lang.Object,
org.apache.commons.validator.ValidatorAction,
org.apache.commons.validator.Field,
org.apache.struts.action.ActionErrors,
javax.servlet.http.HttpServletRequest"
msg="errors.hankaku">
</validator>
(以下略)
これで、何らかの入力に対して(validation.xml内で) hankaku ルールを指定することで全角文字列が含まれていないかチェックが可能になる。validation.xml の formset 子要素に、以下のように加えると ActionForm が受け取る入力パラメータ pageUrl は必ず半角かどうかチェックされる。(まず required がチェックされその後 hankaku がチェックされる)
<form>
<formset>
<field property="pageUrl" depends="required,hankaku">
<arg0 key="URL" resource="false"/>
</field>
(以下略)
あとはリソースファイル(僕の場合 WEB-INF/classes/ApplicationResources.properties) に hankaku ルールに対応するエラーメッセージを記述すればよい。
errors.hankaku={0} に全角文字が含まれています。
リソースファイルの Unicode エンコーディングをお忘れなく。
EnhancedFieldChecks の isHankaku() は GenericValidator のサブクラスに定義して、それを EnhancedFieldChecks でも使うようにしたほうがさらに良いかも。
はじめまして。
現在、Strutsの仕組みについて
理解しているところでして、
この記事とっても参考になりました。
このサイトには他にも有用な情報が
たくさんあり、「お気に入り」に
登録させていただきました。
説明の仕方がポイントを得ていて、
しかも語り口調が形式ばっていたりしなく、
親しみをもって読むことができました。
これからもいろいろと本サイトには
お世話になると思いますが、
よろしくお願いします。