続いて、Webアプリケーションでは避けて通れない、「入力値の検証」の方法を紹介します。Struts 2では、2種類の方法で入力値の検証処理が実装できるようになっています。1つは、プログラミングによる入力検証方法、もう1つが定義による入力検証方法です。入力検証はこれらの他に annotation を利用して定義する方法もありますが、今回は省略します。まずは、プログラミングによる検証方法から紹介しましょう。

プログラミングによる入力検証方法

プログラミングにて入力検証を行う場合、アクションクラス内のvalidateというメソッドに検証ロジックを下記のように実装します。

リスト22: validateメソッドを追加したTop.javaの抜粋

    public void validate() {
        System.out.println("Top validateメソッドIN");
        LinkedList errorMessages = new LinkedList();
        if ( username == null || username.length() == 0 ) {
            errorMessages.add("username field is required.");
        }
        if ( password == null || password.length() == 0 ) {
            errorMessages.add("password field is required.");
        }

        if ( !errorMessages.isEmpty() ) {
            setActionErrors(errorMessages);
        }
    }

上記の例では、入力フィールドusernameまたはpasswordに値が指定されていない場合に、ActionSupportクラスが提供するsetActionErrorsメソッドにエラーメッセージを登録しています。setActionErrorsメソッドには表示したいメッセージを保持したCollectionインタフェースの実装クラスを指定します。

入力検証が失敗したか成功したかの判断は、validateメソッド内でsetActionErrorsメソッドによってエラーメッセージが登録されたかどうかで行うようになっています。このvalidateメソッドは、イベントに対応したアクションクラスのメソッドを呼び出す前に実行されます。入力検証が失敗した場合、本来呼ぶべきアクションクラスのメソッドは呼び出されずに、アクションにて定義されているinputという名前のoutcomeを実行します。inputが定義されていない場合、エラーとなりますので注意してください。また、validateメソッドを実装した場合、そのアクションクラスを呼び出す全てアクションの実行時にvalidateメソッドが実行されますので、注意してください。

ここで、登録したメッセージをJSPにて表示するには<s:actionerror/>タグを用いて、下記のように記述します。

リスト23: エラーメッセージの表示タグを追加したJSP

<%@ page contentType="text/html; charset=UTF-8" %>
<%@ page pageEncoding="Windows-31J" %>
<%@ taglib uri="/struts-tags" prefix="s" %>

<html>
<head>
    <title>こんにちは</title>
</head>

<body>
<h2>はじめましてSturts2です</h2>

<s:actionerror />

<s:property value="attention"/>

<s:form theme="simple">
   ユーザ名:<s:textfield key="username" /><br>
   パスワード:<s:password  key="password" />
 <p>
   <s:submit value="Login"        action="Top_login" />
   <s:submit value="GuestLogin"   action="Top_guestLogin"/>
 </p>
</s:form>

</body>
</html>

<s:actionerror>タグは、エラーメッセージが登録されている場合にそのメッセージを表示するのみのタグです。出力に際しては<ul>タグを自動的に生成し、メッセージの数分整形して出力をしますが、タグへの指定をすることでフォーマットの変更も行えます。

以上の方法によって、検証ロジックをプログラミングにて記述して入力検証を実施することができます。例では、エラーメッセージをプログラム中に定義していますが、前述した「各種メッセージを外部ファイルで管理する方法」を併用することで、エラーメッセージを外部定義ファイルで管理する事もできます。

定義による入力検証方法

次に、定義による入力検証方法を紹介します。この方法は、前述した方法とは異なり入力検証ロジックをプログラミングせずに、XMLファイルへ記述することで実装します。

入力検証のXML定義ファイルは下記のように非常に単純なものです。

リスト24: Top-Top_login-validation.xml

<!DOCTYPE validators PUBLIC
        "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
        "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">

<validators>
    <field name="username">
        <field-validator type="requiredstring">
            <message key="requiredstring"/>
        </field-validator>
    </field>
    <field name="password">
        <field-validator type="requiredstring">
            <message key="requiredstring"/>
        </field-validator>
    </field>

</validators>

上記の例では、Top_loginアクションに対して、usernameとpasswordフィールドの文字列の必須入力検証を定義しています。<message>で指定しているのは、対象のフィールドがエラーの場合に表示するメッセージのキーです。この検証定義ファイルのファイル名は「アクションクラス名-validation.xml」でアクションクラスと同一パッケージに配置します。ただし、この定義の場合、このアクションクラスを実行する全てのアクションで定義した検証が実行されてしまいます。

この状況を避け、アクション毎に検証をOn/Offまたはルールを変更する場合、検証定義のファイル名を「アクションクラス名-アクション名-validation.xml」とします。上記の例では、Top-Top_login-validation.xmlというファイルを定義しているので、Top_loginアクションが実行された場合にのみ有効な検証を定義している事になります。エラーの場合、「プログラミングによる入力検証方法」と同様にinputというアクションのoutcomeが実行されます。エラーメッセージは、フィールド毎に登録されています。このメッセージをJSPで表示するには<s:fielderror>タグを利用して表示します。

各フィールドに対する検証ルールは、requiredstring以外にもintやdouble, date, emailなどが用意されていますが、実際のアプリケーションでは日本語文字列に対する検証ルールが必要になるでしょう。Struts 2ではこのようなアプリケーション独自の検証ルールを追加する方法も提供されています。