LookupDispatchActionを使う

 1つのフォームに複数のSubmitボタンがあり、 どれを押すかによって異なる処理をさせたい場合、 Actionではなく、抽象クラスLookupDispatchAction を継承したクラスを作る方法があります。以下に、その手順を紹介します。

  1. Struts構成ファイル(struts-config.xml)にForm BeanとActionの定義を追加します。

    <form-bean name="FormBeanLookupExample" type="org.apache.struts.validator.DynaValidatorForm">
        <form-property name="orderNumber" type="java.lang.String" />
        <form-property name="action" type="java.lang.String" />
    </form-bean>
    <!-- 中略 -->
    <action path="/ActionLookupExample"
        attribute="FormBeanLookupExample" name="FormBeanLookupExample"
        input="/LookupExampleStart.jsp" scope="request"
        type="shiten.struts.action.ActionLookupExample" parameter="action">
        <forward name="LookupExampleNew"  path="/LookupExampleNew.jsp" />
        <forward name="LookupExampleEdit" path="/LookupExampleEdit.jsp" />
    </action>
    

    ここで、Actionの定義に属性parameterを使うのがみそです。 この属性には、後述のフォームの記述でSubmitボタンに割り当てるリクエスト変数の名前を指定します。
  2. ApplicationResources.propertiesに、Submitボタンに表示する文字列を定義します。 キーの名前は自由ですが、StrutsのFAQで「button.なにがし」という名前が使われていることから、 「button.なにがし」という命名が習慣化しているようです。 ApplicationResources.propertiesについては、 「エラー処理とメッセージ・リソース」のページをご覧下さい。

    button.new=新規登録
    button.edit=編集
    

    この例のように日本語を使う場合は、native2asciiでエンコードするのも忘れずに。 また日本語を使う際には注意点があります。これは後述します。
  3. このActionを呼び出すフォームを持つJSP文書を作成します。

    <html:form action="/ActionLookupExample">
      <html:text property="orderNumber"/><br/>
      <html:submit property="action"><bean:message key="button.new"/></html:submit>
      <html:submit property="action"><bean:message key="button.edit"/></html:submit>
    </html:form>
    

    ここで、html:submitタグのpropertyは1.のActionのparameter属性の値に合わせます。 またボタンのラベルは、2.で定義したメッセージ・リソースを参照するようにします。
  4. Actionクラスを実装します。

    // Created by Xslt generator for Eclipse.
    // XSL :  not found (java.io.FileNotFoundException:  (Bad file descriptor))
    // Default XSL used : easystruts.jar$org.easystruts.xslgen.JavaClass.xsl
    
    package shiten.struts.action;
    
    import java.io.IOException;
    import java.util.*;
    import javax.servlet.ServletException;
    import javax.servlet.http.*;
    
    import org.apache.struts.action.ActionForm;
    import org.apache.struts.action.ActionForward;
    import org.apache.struts.action.ActionMapping;
    import org.apache.struts.actions.LookupDispatchAction;
    
    /** 
     * ActionLookupExample.java created by EasyStruts - XsltGen.
     * http://easystruts.sf.net
     * created on 12-13-2003
     * 
     * XDoclet definition:
     * @struts:action validate="true"
     */
    public class ActionLookupExample extends LookupDispatchAction {
    
        protected Map getKeyMethodMap() {
            Map map = new HashMap();
            map.put("button.new", "processNew");
            map.put("button.edit", "processEdit");
            return map;
        }
    
        public ActionForward processNew(ActionMapping mapping,
                ActionForm form,
                HttpServletRequest request,
                HttpServletResponse response)
                throws IOException, ServletException {
            return mapping.findForward("LookupExampleNew");
        }
    
        public ActionForward processEdit(ActionMapping mapping,
                ActionForm form,
                HttpServletRequest request,
                HttpServletResponse response)
                throws IOException, ServletException {
            return mapping.findForward("LookupExampleEdit");
        }
    }
    

    このクラスは、LookupDispatchActionを継承します。 実装に必要なメソッドは、 getKeyMethodMapメソッドです。 この中で、押されたボタンに書かれているラベルのキーに対して、 どのメソッドが対応するかを定義したMapオブジェクトを作って返すようにします。
    そして、その対応するとされた名前のメソッド(ここではprocessNewとprocessEdit) も例のように実装する必要があります。

ボタンのラベルに日本語を使う場合の注意
 ボタンのラベルに日本語を使う場合は、 リクエスト変数の値としてそのラベルの値が送られてきますが、 正しくこれをデコードできないと対応するメッセージ・リソースがないために、 次のようなエラーが発生することがあります。

Request[/ActionLookupExample] does not contain handler parameter named action

 この場合はStrutsメモの 「request変数のエンコーディングを設定する」のやり方で、 エンコーディングを設定する必要があります。

但し、この方法は面倒です
 なぜかというと、今日では、 StrutsのActionクラスを継承した共通の基底Actionクラスを作るのが一般化しているためです。 LookupDispatchActionを継承する別クラスをわざわざ作らないといけないのでは面倒です。 そこで、Strutsメモのページでご紹介している、 JavaScriptを使った解決策の方が簡単で、分かりやすいと思います。

Server Side Java Index Top

(first uploaded 2003/12/14 last updated 2005/01/30, URANO398)

テレワークならECナビ Yahoo 楽天 LINEがデータ消費ゼロで月額500円〜!
無料ホームページ 無料のクレジットカード 海外格安航空券 海外旅行保険が無料! 海外ホテル