LookupDispatchActionとEventDispatchActionの比較

Googleの日本語で「EventDispatchAction」を検索するとほその日記(2006/04/25)しか見つからない(WEB全体でも少ない・・・)と言われ、それならもう少し詳しく書いておこうかなと思って書きます。実際にコードを書いて検証したわけでなく覚書なので間違ってる所があったらごめんなさい。。。

今更かな?とも思ったんですが次のプロジェクトで使うんでついでに現場教育も兼ねて書きます(ぉ)

■ LookupDispatchActionとはどんなものか

  1. リクエストパラメータの値でメッセージリソースを逆引きする。
  2. 得た値をキーとしてAction内のgetKeyMethodMap()メソッドで定義されたMapの中を検索する(内部的にはキー同士の比較でなくリクエストの値とリソースの値が比較されている)。
  3. 検索した結果得られた文字列を呼び出すメソッド名としてActionのメソッドが呼び出される。

以下、LookupDispatchActionの具体例です(※色が同じ所が関連している所です)

メッセージリソースの内容

button.label.search=検索
button.label.edit=編集
JSPの内容

<html:form method="post" action="">
  <html:submit property="event"><bean:message key="button.label.search"/></html:submit>
  <html:submit property="event"><bean:message key="button.label.edit"/></html:submit>
</html:form>
struts-config.xmlの内容

<action path="/LookupDispatchActionTest"
        type="foo.LookupDispatchActionTest"
        parameter="event"
        name="actionFormName"
        scope="request"
        input="/LookupDispatchActionTest.jsp"/>
Actionの内容

public class LookupDispatchActionTest extends LookupDispatchAction {
  protected Map getKeyMethodMap() {
    Map map = new HashMap();
    map.put("button.label.search", "search");
    map.put("button.label.edit", "edit");
    return map;
  }

  public ActionForward search(
                ActionMapping mapping,
                ActionForm form,
                HttpServletRequest request,
                HttpServletResponse response)
             throws Exception {

    return mapping.findForward("success");
  }

  public ActionForward edit(
                ActionMapping mapping,
                ActionForm form,
                HttpServletRequest request,
                HttpServletResponse response)
             throws Exception {

    return mapping.findForward("success");
  }
}

よく使われているActionクラス(と思う)なので冒頭の説明で事足りると思います。

■ EventDispatchActionとはどんなものか

Struts1.2.9から追加されたクラスでLookupDispatchActionと似ていますが設定がより楽に汎用的にできるようになっています。

以下、上記LookupDispatchActionをEventDispatchActionに書き換えた例です。

JSPの内容

<input type="submit" name="search" value="検索">
<input type="submit" name="hensyu" value="編集">
struts-config.xmlの内容

<action path="/EventDispatchActionTest"
        type="foo.EventDispatchActionTest"
        parameter="search,hensyu=edit,default=init"
        name="actionFormName"
        scope="request"
        input="/LookupDispatchActionTest.jsp"/>
Actionの内容

public class EventDispatchActionTest extends EventDispatchAction {

  public ActionForward search(
                ActionMapping mapping,
                ActionForm form,
                HttpServletRequest request,
                HttpServletResponse response)
             throws Exception {

    return mapping.findForward("success");
  }

  public ActionForward edit(
                ActionMapping mapping,
                ActionForm form,
                HttpServletRequest request,
                HttpServletResponse response)
             throws Exception {

    return mapping.findForward("success");
  }

  /* 特徴あるEventDispatchActionの動きを説明するために追加したメソッド */
  public ActionForward init(
                ActionMapping mapping,
                ActionForm form,
                HttpServletRequest request,
                HttpServletResponse response)
             throws Exception {

    return mapping.findForward("success");
  }
}

動きについて少し詳しく説明します。

特別に理解しなければならないのは、struts-config.xmlのaction定義にある「parameter="search,hensyu=edit,default=init"」の部分です。

  • search (リクエストパラメータのキーにsearchがある場合、searchメソッドが呼び出される[search=searchと同じ意味)
  • hensyu=edit (リクエストパラメータのキーにhensyuがある場合、editメソッドが呼び出される)
  • default=init (parameter=""内のキーがリクエストパラメータのキーに存在しない場合、initメソッドが呼び出される)

つまりEventDispatchActionはリクエストパラメータのキーでstruts-config.xmlのparameter属性を見に行き実行するメソッドを決定しているという事です(内部処理的には逆だったと思いますが意味合い的にはコレでOK)。


■ 比較してとどんなもんか

私はEventDispatchActionの方が好きです。なぜなら設定の記述量が少ないからです。もしボタンが一つ増えた場合でもEventDispatchActionはstruts-config.xmlにメソッド定義を追加して、Actionクラスにメソッドを追加するだけですみます。デバッグ用途で違うメソッドを呼び出したい時なども「hensyu=testEdit」などに変えるだけで良いです。DispatchActionに比べるとセキュリティ的にも安全です。パラメータの値がそのままメソッド名になっているのと違い、明示的に実行するメソッドを定義するので。これに限ればLookupDispatchActionと同じです。

EventDispatchActionの良さは使っていると地味にしみて来ます。例えばページングの処理があったとして、[次へ]や[ページ番号]ボタンをクリックすると必ず「offset」という名のパラメータが送られてくるとします。そうした場合struts-config.xmlにparameter="offset=paging"と書くだけでページング関連の処理をまとめる事ができます。実際の開発でこういう風に開発していましたがとてもスッキリしたコーディングができ、今見ても綺麗なソースだと自負できます(EventDispatchActionだけの成果では無いですが・・・)

いまいちEventDispatchActionが広まっていないようなのでこのような日記を書いてみました。興味を示された方は触ってみてはどうでしょう?