May 23, 2003

Struts Validator 拡張方法

[ Java ]

Jakarta Struts 1.1 の新機能、Validator を拡張する方法。『Jakartaプロジェクト徹底攻略 』と『マスタリング Jakarta Struts』の二冊を読んだけど、どちらにも書いていなかったので忘れないうちにメモしておく。

今回やりたかったのは、Validator でフォームの入力値に全角文字が含まれていないかをチェックするということ。入力の有無やメールアドレスの書式などのチェックを Validator で行ったので、方法を統一するために Validator を拡張して対応する。

Validator を拡張する際に関係するのは、

  • org.apache.struts.validator.FieldChecks クラス
  • WEB-INF/validator-rules.xml
  • WEB-INF/validation.xml
  • メッセージリソースファイル (WEB-INF/classes/*.properties)

の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 でも使うようにしたほうがさらに良いかも。

Posted by naoya at May 23, 2003 08:19 PM | トラックバック (2)  b_entry.gif
トラックバック [2件]
TrackBack URL: http://mt.bloghackers.net/mt/suck-tbspams.cgi/115
Validator の全角チェック
Excerpt: NDO::Weblog: Struts Validator 拡張方法...
Weblog: UCH Blog
Tracked: March 25, 2004 07:14 PM
Validator の全角チェック
Excerpt: NDO::Weblog: Struts Validator 拡張方法
Weblog: UCH Blog
Tracked: March 25, 2004 07:16 PM
コメント [7件]

66

[1] Posted by: Anonymous at September 4, 2003 05:04 PM [返信]

66

[2] Posted by: Anonymous at September 4, 2003 05:04 PM [返信]

はじめまして。
現在、Strutsの仕組みについて
理解しているところでして、
この記事とっても参考になりました。
このサイトには他にも有用な情報が
たくさんあり、「お気に入り」に
登録させていただきました。

説明の仕方がポイントを得ていて、
しかも語り口調が形式ばっていたりしなく、
親しみをもって読むことができました。

これからもいろいろと本サイトには
お世話になると思いますが、
よろしくお願いします。

[3] Posted by: sussudio at September 12, 2003 07:53 AM [返信]

どうもです。

メモ程度にまとめたものでしたが、何かのお役に立てたようで光栄です。Struts の TIPS というかノウハウを忘れないように書き留めようと思っていたんですが、なかなか時間がなくて書かずじまい。

今度ちょっと本腰入れてまとめようと思います。

[4] Posted by: naoya at September 13, 2003 01:08 AM [返信]

ddddddddd

[5] Posted by: Anonymous at November 18, 2003 12:24 PM [返信]

aaa

[6] Posted by: aaa at December 24, 2003 05:14 PM [返信]

現在、Strutsを勉強中なのですが、Validator を拡張する方法ってどうやればいいのかわからずにさまよっている時に、ここにたどり着きました。

暗闇の中に迷っている時に一筋の光が差し込んできたっていうそんな気持ちです。(^^)v
参考にさせていただきます。

ありがとうございました。

[7] Posted by: こだっく at February 13, 2004 09:24 AM [返信]