s2struts1.2のsubmitタグの動作でのforwardがうまくいかない
S2 framework-2.3.23
S2struts-1.2.12
を使用することになったので、いろいろと検証しているのだけれども、ちょっと上手くいっていない。
(スーツな人たちが、このフレームワークのバージョンを指定してきた、個人的にはhotdeploy可能なs2struts1.3またはSAStrutsがよいのだけれども、使ったことがないから、このバージョンになったとか聞いた。)
S2Strutsタグライブラリを使用して、
以下のようなサブミット時に実行するコンポーネントとメソッドを指定する事が可能とのことで
Actionクラスが異なっても、メソッドが実行できると思って、楽に使えるのではないか?と思いためしてみた。1つの画面に進んで来る場合と戻ってくる場合を1つのAtionで別々のメソッドで実行できばいいかなと考えた。戻り先を動的に変更したいと思ってね。
<html:form action="/hoge1"> <s2struts:submit action="#{hoge1Action.execute}"><bean:message key="toNext"/></s2struts:submit> <s2struts:submit action="#{hoge2Action.execute}"><bean:message key="toBack"/></s2struts:submit> </html:form>
として、submitで、それぞれのActionは実行される(デバッグにて確認済)。 hoge1Action.executeは問題なく動作できる。しかし、hoge2Actionにおいてforwardがうまくいかない。うまくいかないっていうのは、ログでは以下のように出力される。
WARN org.apache.struts.action.ActionMapping - Unable to find 'success2' forward.
struts-config.xmlでは、以下のようになっていて、リクエスト処理自体はデバッグにて確認済みの hoge2Action.executeが実行され、hoge2Action.executeでは、return "success2"を戻しているのだけれども、最終的なforward時にaction=/hoge1 というリクエストに基づいて /hoge1 での forward先にsuccess2が存在していなくて、forwardがうまくいっていない。
<action path="/hoge1" type="jp.co.samples.web.action.hoge1Action" name="hogeForm" scope="request" validate="false"> <forward name="success" path="/jsp/hoge1.jsp" /> </action> <action path="/hoge2" type="jp.co.samples.web.action.hoge2Actionn" name="bForm" scope="request" validate="false"> <forward name="success2" path="/jsp/hoge2.jsp" /> </action>
なんとか、できないものなのかな〜。もしかしてS2Strutsタグライブラリでは、
S2Struts1.3.0-RC3以降では、指定したコンポーネントに対応するActionMappingが使用されます。
とあるけど、調べてないから何とも言えないけどs2struts1.3では、そのあたりが改良されていたりするのかな。
javaScript側で、hoge2のsubmit時にaction先を変更しないと無理なのか。
もしくは、共通用のActionを用意して、そのAction内で、それぞれのhoge1.doやhoge2.doにforwardさせるしかないのかな
例えば、jsp側でsubmitボタンのproperty="hoge1"をセットしておけばHttpServletRequestの getParameterMap()内にkeyとして、そのhoge1が存在するから、そのpropertyに対応するMapを用意しておき、そのMap 内からhoge1の遷移先のforwardを取り出すといった方法かな〜。でも、これだと設定が2箇所に分かれてしまう(forwardを管理するMap とstruts-config.xmlの両方に意識して設定しなきゃならん)。
例えばのsample
<form action="/hoge" name="baseForm"> <html:submit property="hoge1" value="戻る"/> <html:submit property="hoge2" value="次へ"/> </form>
<action path="/hoge" type="jp.co.samples.web.action.CommonAction" name="BaseForm" scope="request" validate="false"> <forward name="hoge1" path="/hoge1.do" /> <forward name="hoge2" path="/hoge2.do" /> <forward name="hoge3" path="/hoge3.do" /> </action>
java系のsampleソース
public class CommonActionImpl implements CommonAction { private HttpServletRequest request; private CommonActionSortService commonActionSortService; public void setCommonActionSortService(CommonActionSortService commonActionSortService) { this.commonActionSortService = commonActionSortService; } public void setRequest(HttpServletRequest request) { this.request = request; } public String excute() { Map<String, String[]> requestParameterMap = request.getParameterMap(); for (Map.Entry<String, String[]> entry : requestParameterMap.entrySet()) { String forward = cmaCommonActionSortService.sort(entry.getKey()); // log.debug("key=" + entry.getKey() + " value=" + entry.getValue()); if (forward != null) { return forward; } } System.err.println("ERROR no-action-foward FORWARD先がありません。"); return "index"; } }
public class CommonActionSortServiceImpl implements CommonActionSortService { private HashMap<String, String> forwardMap = new HashMap<String, String>(); public String sort(String param) { if (forwardMap.containsKey(param)) { return param; } else { return null; } } public void setForwardMap(HashMap<String, String> forwardMap) { this.forwardMap = forwardMap; } }
2008-06-17追記
id:taedium さんの http://d.hatena.ne.jp/taedium/20080616/p1
にてs2strutsを使用した場合の推奨パターンが記載されています。ポイントは、
基本的にjspとActionFormとActionとInitActionは1対1対1対1で作成
Forwardされた先のjspでは s2struts:init タグにより画面表示に必要な情報を取得するInitActionを呼び出します。
なのかな。ものすごーく参考になります。自分のやり方は、突貫工事のようでよろしくないですね。
こうゆう設計方針が、未熟者にとっては、リファレンスなどに記載してあると良いように思う。