JAXSON 業務アプリケーションフレームワーク
トップ

インストール

ドキュメント
チュートリアル
開発ガイド
トランザクション管理
データベース接続
データベースアクセス
バリデーション
セキュリティ
エクセルファイル出力
JavaScriptリファレンス
API doc

ダウンロード
jaxson-2.1.zip

バリデーション

入力された値のチェックやデータベースに登録するカラムの値チェックを行います。

バリデータの設定
バリデーションの設定はチェックを行うフィールドの FeildDEF 注釈で行います。
/** 必須項目 */
@FieldDEF(validator=RequiredValidator.class)
private String userID;
バリデータがパラメータを要求する場合は FieldDEF#validatorParams で指定します。複数のパラメータが必要な場合はカンマで区切ります。
/** 20バイトを超えるとエラー */
@FieldDEF(
    validator = MaxByteLengthValidator.class,
    validatorParams = "20, MS932"
)
private String userName;
複数のチェックを行う場合は配列で指定します。 この場合は validator と validatorParams を対応させなくてはなりません。
/** 必須チェックとバイト数チェックを行う */
@FieldDEF(
    validator = { RequiredValidator.class, ByteLengthValidator.class },
    validatorParams = { "", "8, MS932" }
)
private String zipCode;
FieldDEF#displayNameにフィールドの論理名をセットしておくと、 バリデーションエラーの際にメッセージにフィールド名ではなく論理名が表示されます。
また validatorMessage でメッセージを指定することができます。
@FieldDEF(
    validator = { RequiredValidator.class, ByteLengthValidator.class },
    validatorParams = { "", "6, MS932" },
    validatorMessage = { "%1$sは必須項目です。", "%1$sは%3$s文字以内で入力してください。"},
    displayName = "郵便番号",
)
private String zipCode;
メッセージは java.util.Formatter の書式でフォーマットされます。
フォーマットは第一引数に ValidatorResult#getDisplayName()で取得する名称、 第二引数に値オブジェクト、第三引数以降に FieldDEF#validatorParams で指定したパラメータが順に渡されます。
上記例だと 「郵便番号は必須項目です。」「郵便番号は6文字以内で入力してください。」となります。

バリデーションの実行
バリデーションの実行は FieldValidator.validate(Object) により行います。 このメソッドは妥当性チェックエラーがあった場合でも全てのフィールドのチェックを実行し、 エラーの時に作成したValidatorResultオブジェクトを格納したListを返します。 エラーがなかった場合は空のListになります。
// formBeanはチェック対象オブジェクト
List<ValidatorResult> results = FieldValidator.validate(formBean);
if (!results.isEmpty()) {
    String message = "";
    for (ValidatorResult result : results) {
        message += result.getDisplayName() + " : " + result.getMessage() + "\n";
    }
    log.log(Level.WARNING, message);
    return;
}
...
テーブルの1レコードを表現するエンティティクラスの場合は 新規に登録する場合は必須でも、更新の場合はそのカラムの必須チェックは不要です。 FieldValidator.validate(Object,boolean) の第二引数にfalseを渡すと必須チェックを行いません。

ServiceActionのバリデーション
ServiceActionのサブクラスではアクション呼出し時にバリデーションを行うように設定できます。
public class XXXAction extends ServiceAction {

    @ContextParam    // プリミティブ型、基本型の場合はvalidatorを指定
    @FieldDEF (validator = RequiredValidator.class)
    String requiredString;

    @ContextParam    // Beanオブジェクトはvalidationにtrueを指定
    @FieldDEF (validation = true)
    private XXXFormBean formBean;
    
    public void execute() throws Exception {
        ...
    }
}

// クライアントから渡されるパラメータを格納するクラス
public class XXXFormBean implements Srializable {

    @FieldDEF(validator=RequiredValidator.class)
    private String userID;
    
    @FieldDEF(
        validator = MaxByteLengthValidator.class,
        validatorParams = "20, UTF-8"
    )
    private String name;
    
    @FieldDEF(
        validator = GenericFieldValidator.class,
        validatorParams = "isEmail"
    )
    private String mail;
    
    public String getUserID() { return userID; }
    public String getName() { return name; }
    public String getMail() { return mail; }
}

**** HTML ****

<form id="updateForm">
    ユーザID <input type="text" id="userID"/><br/>
    名前 <input type="text" id="name"/><br/>
    メール <input type="text" id="mail"/><br/>
    <input type="button" value="登録"
        onclick="doForm('XXXAction',$('updateForm'),'next.html')"/>
</form> 
バリデーションエラーがあった場合に処理を中止してクライアントにメッセージを表示します。
但し、レスポンダの指定でアクションの出力がテキストやバイナリデータの場合には アラートを表示するJavaScriptを返すのは適切でないために何もレスポンスには返しません。
このケースで何らかのレスポンスを返すためにはアプリケーションで実装する必要があります。
@Responder(JpegImageResponder.class)
public class SearchImageAction extends ServiceAction {

    @Override
    public void doError(Exception e) throws Exception {
        if (e instanceof ValidatorException) {
            ...    // バリデーションエラー時の処理
        } else {
            super.doError(e);
        }
    }
} 

データベースのカラム値チェック
エンティティから検索条件を抽出する Persister#find(E)、Persister#update(E)、Persister#delete(E) ではSQL実行前に主キーカラムの必須チェックを行います。
GenericPersisterでは 更新、登録時にエンティティオブジェクトのバリデーションを行います。
バリデーションの内容はエンティティクラスのフィールドに注釈されたFieldDEFの指定に従います。 但し必須チェックはUPDATEで更新対象のカラム値として扱われる場合についてはチェックを行いません。 値を設定しなかったカラムは FieldDEF#acceptNull もしくは FieldDEF#acceptBlank で指定しない限り 更新されずに既存の値のままとなります。

必須チェック
必須チェックには RequiredValidator クラスを指定します。 下記のGenericFieldValidator は、フィールドの値が null もしくは空文字列の場合はチェックを行いませんので GenericValidator#isBlankOrNull(String)は使用できません。

GenericFieldValidator
Apatche Commons Validator の GenericValidator のラッパーです。 基本的なチェックはこれを使用します。
このバリデータの引数として 1番目に GenericValidator のメソッド名を 2番目以降にメソッドの2番目以降の引数を指定します。 メソッドの第一引数にこのフィールドの値が渡されます。
呼び出す GenericValidator のメソッドは メソッド名が指定されたものと一致し、 かつ引数の数がパラメータの数と一致し、 かつ第一引数がフィールドの型と一致するものが選択されます。
// GenericValidator#isInRange(long,long,long) を実行する
@FieldDEF(
    validator = GenericFieldValidator.class,
    validatorParams = "isInRange, 100, 999"
)
private long number; 
フィールドの値が null もしくは空の文字列の場合はチェックを行いませんので、 必須チェックが必要な場合は必ず GenericFieldValidator の前に RequiredValidator を指定してください。
@FieldDEF(
    validator = { RequiredValidator.class, GenericFieldValidator.class },
    validatorParams = { "", "isLong"}
)
private String code;


バイト長チェック
文字数をバイトで数えるバイト・セマンティクスがデータベースのデフォルトであるケースが多いため、 文字セットによってバイト長が変わる日本語を含む文字長チェックは悩みの種です。
文字列のバイト長のチェックとして ByteLengthValidator, MaxByteLengthValidator を用意しています。
このチェックには文字セットを指定します。
// 文字セットを'MS932'で 12バイトを超えないことを検証
@FieldDEF (
    validator = MaxByteLengthValidator.class,
    validatorParams = "12, MS932"
)
private String name; 
validatorParamsで文字セットが指定されていない場合、 WEB-INF/application-settings.xml の 'database-charset'パラメータの値が使用されます。


クライアントの実装
バリデーションエラーの場合、ValidatorExceptionがスローされて デフォルトではクライアントで警告メッセージを表示します。
システムによっては メッセージエリアにメッセージを表示させたり、 フォーム要素のスタイルを変えてユーザに注意を促したりする場合が多いと思いますが、 このような場合は他の例外処理と同様にJavaScriptの関数 onActionError を用意しておくとこの動作をカスタマイズすることができます。
バリデーションエラー時に onActionErrorに渡されるオブジェクトは下記のようになります。 エラーの要素を赤で表示するには下記のようにします。 入力がない場合には赤くはならないですが...
function onActionError(errorInfo) {
    if (errorInfo.ERROR.className == "ValidatorException") {
        var validatorResults = errorInfo.ERROR.validatorResults;
        for (var i = 0; i < validatorResults; i++) {
            var fieldName = validatorResults[i].fieldName;
            Element.setStyle($(fieldName), { color : "red" });
        }
    } else {
        ...
    }
}