Actionクラスと入力チェック
次にActionクラスと、入力チェックの実装です。なお、入力チェック機能は以前紹介しましたStruts 2の新たな検証機能「OVal Frameworkプラグイン」を利用しても良いですし、従来のValidationを利用しても同じ結果になります。
なお、今回の入力チェック機能はAJAXを利用したものになるので、次の決まりごとがあります。
- struts.propertiesでstruts.enableJSONValidation=trueを宣言する
- ActionクラスのインターセプタにjsonValidationWorkflowStackを利用する
ではActionクラスの実装例を見てみましょう。
@InterceptorRefs({ // AJAXを利用したValidation利用時に宣言 @InterceptorRef("jsonValidationWorkflowStack"), }) …(省略)… public class SampleAction extends ActionSupport { private static Logger log = Logger.getLogger(SampleAction.class); // 初回リクエスト時に呼ばれる。入力チェックなし。 @Action("") @SkipValidation() public String execute() throws Exception { return "success"; } // 「送信する」ボタンによって呼ばれる。 @Action("check") public String check() throws Exception { log.debug("*check*"); return "success"; } …(中略)… // リクエストパラメータが格納されるクラス private SampleModel model; public SampleModel getModel() { return model; } // 入力チェック機能をSampleModelクラスに委譲する // appendPrefix=falseとすることで、エラー情報に接頭辞をつけない @VisitorFieldValidator(appendPrefix=false) public void setModel(SampleModel model) { this.model = model; }
Actionクラスの入力チェックは、ソース最下部にある@VisitorFieldValidatorとsetModel()の箇所にあるように、実際の入力チェックはSampleModelに委譲されることを宣言しています。ではそのSampleModelクラスを一部見てみましょう。
public class SampleModel { private String name; …(省略)… public String getName() { return name; } /** * @param name セットする name */ // 必須入力 @RequiredStringValidator(trim=true , key="field.error.name.require" , shortCircuit=true) // 入力文字長のチェック。4~8文字まで。 @StringLengthFieldValidator(trim=true , key="field.error.name.length" , minLength="4" , maxLength="8", shortCircuit=true) // 他フィールド間のチェック。パスワードに入力された内容が名前に含まれてはいけない。 @FieldExpressionValidator( key="field.error.password.notname" , expression = "password.indexOf(name) lt 0",shortCircuit=true ) public void setName(String name) { this.name = name; } …(以下、set/getメソッドとValidation定義)… }
Validationの機能についてはStruts 2入門(2)~バリデーションの仕組みを理解する(前編)~ならびにStruts 2入門(3)~バリデーションの仕組みを理解する(後編)~を参考にしてください。
今回は一番複雑な処理を行っているユーザ名(name)にフォーカスを絞って解説します。
Validation | 詳細 |
RequiredStringValidator | 必須入力チェック。 |
StringLengthFieldValidator | 文字列長チェック。mixLengthが最小値、maxLengthが最大値。 |
FieldExpressionValidator | 他フィールドとの関連をチェックする。条件式(if文など)を1つ記述可能。 |
他、trim属性で入力値の両端にある空白を削除、shortCurcuit属性で、チェックエラーを検出した段階で中断することもできます。
では実際に[送信する]ボタンを押して確認します。すべて空欄にした際のチェック結果は図のようになります。[送信する]ボタンを押した際にはAJAXを利用して送受信が行われています。
では他に値をいくつか入れてみます。先ほどのnameフィールドに使われている入力チェックで、パスワードに名前が含まれていた場合にエラーとする定義がありましたので、名前にuser、パスワードにuser12と入力して、再度「送信する」ボタンをクリックします。
確かにチェックされた内容が出力されました。
このエラーメッセージの出力についてですが、Struts 2 jQueryプラグインでは自動的にエラー情報を取得することまでは行いますが、エラーメッセージを出力するタグや文字列を生成するところは一部ソースを記述します。この出力部分はStruts 2 jQuery Pluginにも記載されている通りです。では具体的な実装例を示します。
<script language="JavaScript" type="text/javascript"> $(document).ready( function() { // エラーメッセージをすべて消去する $.subscribe('removeErrors', function(event,data) { // Actionクラスのエラーメッセージ表示を削除 $('.errorLabel').html('').removeClass('errorLabel'); // 各入力項目のエラーメッセージ表示を削除 $('#formerrors').html(''); }); }); <!-- 送信するボタンを押した際に稼動する --> function customValidation(form, errors) { // 各入力フォームのエラー部分 var list = $('#formerrors'); // Actionクラスのエラー(ActionErrors)があった場合にメッセージを表示 if (errors.errors) { $.each(errors.errors, function(index, value) { list.append('<li>'+value+'</li>\n'); }); } // 各フィールドの入力チェックエラー(FieldErrors) if (errors.fieldErrors) { $.each(errors.fieldErrors, function(index, value) { // フィールド名+ErrorのIDのHTML要素に対してエラーメッセージを出力 var elem = $('#'+index+'Error'); if(elem) { elem.html(value[0]); elem.addClass('errorLabel'); } }); } } </script> </head> <body> <div id="result">以下の項目に入力して「送信する」ボタンを押してみましょう。 <!-- Actionクラスでのエラーを表示する --> <ul id="formerrors" class="errorMessage"></ul> <s:form id="formValidate" theme="xhtml" cssClass="yform" onsubmit="return false;"> <!-- 入力フォームと送信ボタン --> <div class="type-text"> 名前(name) : <s:textfield id="name" name="model.name" theme="simple" title="ユーザ名"/> <label for="echo"><span id="nameError"></span></label> </div> …(省略)… <sj:submit targets="main" button="true" validate="true" validateFunction="customValidation" onBeforeTopics="removeErrors" onSuccessTopics="removeErrors" value="送信する" href="check"></sj:submit> …(省略)…
変更している場所は、JavaScript(jQueryを利用)と、送信ボタンの<sj:submit>です。
JavaScriptの部分は、Struts 2のActionクラスから渡されたエラー情報を解析して、実際のHTML要素に対してテキストを出力しています。送信ボタンの部分で、AJAX Validationに関連する属性がいくつかつけられており、これが稼動する仕組みになっています。今回利用したそれぞれの属性については以下のようになっています。
属性名 | 概要 |
targets | 非同期レスポンスを受け取った後に更新するHTML要素のID名。合致するものがない場合は画面を更新する。 |
button | 送信ボタンを使うか否か。falseの場合にはリンクになる。 |
validate | AJAX Validation機能を使う場合にtrueを使う。 |
validateFunction | AJAX Validation機能を使い、Struts 2から返された後に起動するJavaScript関数を指定する。 |
onBeforeTopics | フォームを送信する前に起動するJavaScript関数名。 |
onSuccessTopics | エラーがなかった場合に起動するJavaScript関数名。 |
value | 表示テキスト。 |
href | 送信するURL。 |