11. 入力チェック

WebWork2での入力値のチェックはActionクラス内に入力チェックのロジックを書くか、設定ファイルを書いて入力チェックをする2つの方法があります。

Actionクラス内での入力チェック

ValidateBySelfActionの作成

ActionSupportは元々Validatableインターフェースを実装しているので、validate()メソッドをオーバーライドし、nameパラメータが未入力の場合はaddFieldError()でエラーメッセージを設定します。

public class ValidateBySelfAction extends ActionSupport {
    private String name;

    public String execute() throws Exception {
        return SUCCESS;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void validate() {
        if (StringUtils.isEmpty(name)) {
            addFieldError("name", "名前を入力してください");
        }
    }
}
xwork.xmlの設定

validateinitは初期表示なのでvalidate.vmを表示するだけです。
validateは入力チェックを行うのでintercepterにvalidationWorkflowStackを設定します。
入力チェックでエラーがあった場合はname="input"で指定されたresultへ、そうでない場合はname="success"で指定されたresultを表示します。

<action name="validateinit" class="com.opensymphony.xwork.ActionSupport">
    <result name="success" type="dispatcher">
        <param name="location">/WEB-INF/vm/validatebyself.vm</param>
    </result>
</action>
<action name="validate" class="ww2.examples.event.ValidateBySelfAction">
    <interceptor-ref name="validationWorkflowStack"/>
    <result name="success" type="dispatcher">
        <param name="location">/WEB-INF/vm/validate_result.vm</param>
    </result>
    <result name="input" type="dispatcher">
        <param name="location">/WEB-INF/vm/validatebyself.vm</param>
    </result>
</action>
validatebyself.vm

入力フォームとエラーメッセージを表示します。

<form action="validatebyself.action">
#if($action.fieldErrors.get("name"))
    <font color="red">
        #foreach($message in $action.fieldErrors.get("name"))
            $message<br />
        #end
    </font>
#end
    
    名前:
    <input type="text" name="name" value="$!name" />
    <input type="submit" value="送信" />
</form>
validate_result.vmの作成

入力された名前を表示するだけです。

ようこそ!$nameさん

設定ファイルを使った入力チェック

準備

validators.xmlwebwork-example.warからsrcの直下にコピーします。

<validators>
<validator name="required"
 class="com.opensymphony.webwork.validators.JavaScriptRequiredFieldValidator"/>
<validator name="requiredstring"
 class="com.opensymphony.webwork.validators.JavaScriptRequiredStringValidator"/>
<validator name="int"
 class="com.opensymphony.webwork.validators.JavaScriptIntRangeFieldValidator"/>
<validator name="date"
 class="com.opensymphony.webwork.validators.JavaScriptDateRangeFieldValidator"/>
<validator name="expression"
 class="com.opensymphony.xwork.validator.validators.ExpressionValidator"/>
<validator name="fieldexpression"
 class="com.opensymphony.xwork.validator.validators.FieldExpressionValidator"/>
<validator name="email"
 class="com.opensymphony.webwork.validators.JavaScriptEmailValidator"/>
<validator name="url"
 class="com.opensymphony.webwork.validators.JavaScriptURLValidator"/>
<validator name="visitor"
 class="com.opensymphony.webwork.validators.JavaScriptVisitorFieldValidator"/>
<validator name="conversion"
 class="com.opensymphony.xwork.validator.validators.ConversionErrorFieldValidator"/>
<validator name="stringlength"
 class="com.opensymphony.xwork.validator.validators.StringLengthFieldValidator"/>
</validators>
ValidateActionの作成

ValidateBySelfActionからvalidate()メソッドを取り除いただけです。

public class ValidateAction extends ActionSupport {
    private String name;

    public String execute() throws Exception {
        return SUCCESS;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
ValidateAction-validation.xmlの作成

validationの設定ファイルは、Actionクラスと同じパッケージ上に「アクションクラス名-validation.xml」という名前で作成します。

<?xml version="1.0" encoding="Shift_JIS"?>
<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0//EN" 
    "http://www.opensymphony.com/xwork/xwork-validator-1.0.dtd">
<validators>
    <field name="name">
        <field-validator type="requiredstring">
            <message>名前を入力してください</message>
        </field-validator>
    </field>
</validators>
xwork.xmlの設定

Action内での入力チェックの時とほとんど同じです。

<action name="validateinit" class="com.opensymphony.xwork.ActionSupport">
    <result name="success" type="dispatcher">
        <param name="location">/WEB-INF/vm/validate.vm</param>
    </result>
</action>
<action name="validate" class="ww2.examples.event.ValidateAction">
    <interceptor-ref name="validationWorkflowStack"/>
    <result name="success" type="dispatcher">
        <param name="location">/WEB-INF/vm/validate_result.vm</param>
    </result>
    <result name="input" type="dispatcher">
        <param name="location">/WEB-INF/vm/validate.vm</param>
    </result>
</action>
validate.vmの作成

formのctionの飛び先以外はvalidatebyself.vmと同じです。

<form action="validate.action">
#if($action.fieldErrors.get("name"))
    <font color="red">
        #foreach($message in $action.fieldErrors.get("name"))
            $message<br />
        #end
    </font>
#end
    
    名前:
    <input type="text" name="name" value="$!name" />
    <input type="submit" value="送信" />
</form>

独り言

個人的には設定ファイルでの入力チェックは面倒だと思います。デバッグもしづらいし、標準のValidatorで出来ないチェックがあると自分で実装しないといけないし。
基本的にはAction内でやった方が自由度が高いので融通が利きます。
設定ファイルを使った場合のメリットとしてはクライアントサイドでJavaScriptによる入力チェックも同じ設定ファイルで行えることでしょう。
両方の併用することも出来るので、単純なチェックは設定ファイルで行って、複雑なチェックの場合はAction内で行うのもいいかもしれません。
なおValidationの細かい検証などは行っていません。StringLengthFieldValidatorとかはString.length()使って長さ取ってるみたいなので、全角文字とかで問題おきそうだけど…。