SAStrutsでAjaxリクエストのエラーメッセージを表示する方法

SAStrutsでは、入力チェックをFormのアノテーションや、メソッドを定義することで実行することができます。
特にFormのアノテーションによるチェックは、表示するエラーメッセージの処理を独自で書く必要がなく、フレームワークで請け負ってくれるため非常に便利です。

しかし、エラーメッセージの表示には画面の再描画(画面遷移)が必要となるため、Ajaxによる非同期通信ではこの恩恵を受けることができません。

そこで、AjaxリクエストでもFormのアノテーションによる入力チェックと、エラーメッセージの表示を行う方法を紹介します。

環境

入力画面

まずは、入力画面の抜粋です。入力項目に「ユーザID」と「パスワード」を準備しました。「ログイン」ボタンは、Ajaxで処理するため[type="button"]としています。対応するFormクラスでは、「ユーザID」と「パスワード」の両方に[@Required]を設定します。

<!-- Ajax処理のエラーメッセージ表示域 -->
<div id="ajaxErrorMessage"></div>

<!-- Ajax処理のリクエストパラメータ -->
<s:form styleId="form" styleClass="form-horizontal">
<legend>入力</legend>
<div class="control-group">
 <label class="control-label">ユーザID</label>
 <div class="controls">
  <html:text property="userId" styleId="userId" styleClass="input-xlarge" maxlength="10"/>
 </div>
</div>
<div class="control-group">
 <label class="control-label">パスワード</label>
 <div class="controls">
  <html:password property="passwd" styleId="passwd" styleClass="input-xlarge" maxlength="15"/>
 </div>
</div>
<div class="control-group">
 <div class="controls">
  <input type="button" class="btn btn-primary" id="login" name="login" value="ログイン"/><i class="icon-ok icon-white"></i>
 </div>
</div>
</s:form>

https://lh6.googleusercontent.com/-Z7dRrnRuenI/UNBeW5jyIgI/AAAAAAAANyY/gxDLGGBFN4U/s800/inputform.jpg

Actionクラス

Actionクラスでは、Ajaxを受け付けるloginメソッドと、入力エラー時処理を行うajaxErrorメソッドを準備しました。Executeアノテーションのvalidate属性に[@]とし、Formクラスのアノテーションによる入力チェックを実行します。

    @Execute(validator=true, validate="@", input="ajaxError")
    public String login(){
     
     /* ログイン処理 */
     
     /* レスポンスに対する処理 */

     return null;
    }
    
    @Execute(validator=false)
    public String ajaxError(){
     
     /* リクエストからメッセージオブジェクトを取出す。 */
     HttpServletRequest request = RequestUtil.getRequest();
     ActionMessages messages = (ActionMessages)request.getAttribute(Globals.ERROR_KEY);
     if(messages==null) return null;
     
     /* application(_ja).propertiesの定義を利用してメッセージを生成する。 */
     List<String> messageList = new ArrayList<String>();
     for(Iterator<?> iter = messages.get(); iter.hasNext();){
      ActionMessage msg = (ActionMessage)iter.next();
      messageList.add(MessageResourcesUtil.getMessage(msg.getKey(), msg.getValues()));
     }
     
     /* 
       メッセージをjson形式に変換して、レスポンスを返す。 
       ここで設定している[status]は、JavaScript側でエラーの有無を判断するのに利用する属性です。
     */
     Map<String, Object> map = new HashMap<String, Object>();
     map.put("status", false);
     map.put("messages", messageList);
     String json = JSON.encode(map);
     ResponseUtil.write(json);
     
     return null;
    }

JavaScript

入力エラーの場合に、json形式で返されたメッセージを整形して表示する処理を定義しています。あと、serializeArray()はForm要素内の入力値をjson形式で返します。便利なのでオススメです。

<script>
//ログインボタン イベントのバインド
$(document).ready(function(){
 $('#login').bind('click', function(event){
  validator();
 }); 
});

//ログインボタン押下処理
function validator(){
 $.ajax({
  type:'get',
  dataType:'json',
  url:'${f:url("/login")}',
  cache:false,
  data:$('#form').serializeArray(),
  success:function(json){
   if(json.status==false){
    //エラーが発生した場合、エラーメッセージを表示する要素を組立てる。
    var elem = '<div class="alert alert-error"><ul>';
    for(i in json.messages){
     elem += '<li>'+json.messages[i]+'</li>';
    }
    elem += '</ul></div>';
    //Ajax処理のエラーメッセージ表示域に、エラーメッセージを挿入する。
    $('#ajaxErrorMessage').html(elem);
    return;
   }
   //正常時処理
  },
  error:function(jqXHR, textStatus, errorThrown){
   //異常時処理
  }
 });
}
</script>

実行結果

エラーメッセージが表示されました。
https://lh5.googleusercontent.com/-7vyZqLx4N7M/UNBd9nOSx5I/AAAAAAAANyA/Ef6Q0lofq5Q/s800/showmessage.jpg

まとめ

これで、AjaxリクエストでもFormのアノテーションによる入力チェックと、エラーメッセージの表示を行うことができました。通常の入力チェック処理と、Ajaxの入力チェック処理を分けることなく実装できるので開発効率も良いのではないでしょうか。

ではでは(*´ω`*)ノシ