S2StrutsでAJAX

今あるS2Struts+MayaaベースのWebアプリに、JQuery入れて簡単なAjaxをやらせることを考えてみました。
作り方にもよりますが、ここでは、アクションメソッドの中でレスポンスを生成してしまい、どこにもフォワードしないで終了する形にしてみます。このへんの動きは、S2Strutsでなくとも、Strutsをベースにしたものなら大体同じです。

ポイントは、S2Strutsだと、普通の画面遷移の場合、サブミットボタンは<s2struts:submit>タグで実装しますが、これがちょこっとBase64がかかってたりするので、これをAjax呼び出しに置き換えるということ。その際、あんまり長々と書くのもいやなので、Mayaa<m:exec>を使って少しでも楽して書きたい。

例によって会社で試したので、思い出し書きになりますが、大体こんな感じ。
ここではめんどくさいのでJavaScriptはobtrusive(htmlに埋め込んじゃった)

/WEB-INF/page/emp/detail.html(一部)

 <span style="display:none;" id="paramName">仮paramName</span>
 <script src="../js/jquery-1.2.6.min.js"></script>
 <script type="text/javascript">
  $(function() {
     // id="paramName"なspanの中に書かれてる値をとっておく 
     var $paramName = $('#paramName').text();
     // なんかボタンが押されたら
     $('#clickToShow').click(function() {
       // XMLHttpRequestで非同期アクセスしちゃう
       $.ajax({
         dataType: 'json',
         data: { 渡すデータ },
         type: 'POST',
         url: 'detail.do',
         success: function(emp, status) {
             $('#result').html('<dl>'+
                                 '<dt>'+emp.name+'</dt>'+
                                 '<dd>'+emp.sal+'</dd>'+
                               '</dl>');
         }
      });
     });
  });
 </script>

/WEB-INF/page/emp/detail.mayaa(一部)

 <!-- action()定義を読み込んで -->
 <m:exec src="/WEB-INF/mayaa-js/action.js" />
 <!-- それ使ってアクションメソッド呼び出しをエンコードしてparamNameを生成 -->
 <m:write m:id="paramName" m:replace="false" id="paramName" 
   value="${action('emp_detailAction.doGetDetail')}" />

/WEB-INF/mayaa-js/action.js

 //このJavaScriptはMayaaによって読み込まれRhinoに解釈される
 var action = Packages.com.example.s2struts.Functions.action;

Functions.java

 package com.example.s2struts;
 import java.util.HashMap;
 import org.seasar.struts.Constants;
 import org.seasar.struts.util.Base64ParameterUtil;
 
 public class Functions {
   public static String action(final String name) {
      return Base64ParameterUtil.encode(new HashMap() {
          { put(Constants.ACTION_EXPRESSION_KEY, name); }
      });
   }
 }

rootpackage.web.emp.DetailAction.java(一部)

 public class DetailAction {
    public String doGetDetail() {
      //ajaxでわたってきたデータを受け取る(略)
      
      bean = service.selectBean();
      OutputStream out = response.getOutputStream();
      try {
        //JSONICでてきとうに返す
        JSON.encode(bean, out);
      } finally {
        IOUtils.closeQuietly(out);
      }
      return null;
    }
 }