[Seasar-user:15641] [S2JSF]forEach利用時のhistory back時の挙動について

伊東 伸浩 [E-MAIL ADDRESS DELETED]
2008年 9月 3日 (水) 20:17:53 JST


お世話になります。
伊東と申します。

s2-framework-2.3.11
s2-extension-2.3.11
s2jsf-1.0.16
を使用しております。

下記のような、実装をしている一覧画面にて、history backを使用した場合の
挙動についてご質問いたします。

対象の画面の構成は下記の通りとなります。
・ページング処理を行っている。
・"s:forEach"を使用して一覧を表示している。
・各行に詳細画面へのリンクが設けられており、"f:param"で対照データのIDを送信している。
・詳細画面へのリンクが押されると、m:action="#{orderListAction.doOrderDetailLinkClick}"
 というように自アクションのメソッドが呼び出される。
・doOrderDetailLinkClickメソッドにてIDのパラメータを受け取り、詳細画面へforwardする。


ここで、下記のような操作を行うと選択したデータと実際に表示される詳細画面のデータが異なるという
現象が発生します。
1.一覧の1ページ目を表示する。
2.ページングにて2ページ目に遷移する。
3.history backを使用して1ページ目に戻る。
4.1ページ目の1番目の詳細画面へのリンクを押すと、2ページ目の一番目の成功で詳細画面が表示される。

リンクにてIDをrequest parameterとして送信しているにもかかわらず、
そのIDよりも、前画面で表示されていたIDが処理されていることになります。


そこで、requestの受け渡しを行っている部分にログを埋め込んで調べてみました。

■ログ埋め込み対象のメソッド
 ・UIParameterUtil.saveParamsToRequest()
 ・BindingUtil.getValue()
 
************************************************************************************
【UIParameterUtil.saveParamsToRequest()】

	public static void saveParamsToRequest(UICommand command, HttpServletRequest request) {
		List children = command.getChildren();
		for (int i = 0; i < children.size(); ++i) {
			UIComponent child = (UIComponent) children.get(i);
			if (child instanceof UIParameter) {
				UIParameter param = (UIParameter) child;
          if ("btkOrderId".equals(param.getName())) {    // 特定のパラメータの場合、ログを出力
              System.out.println("request.setAttribute(" + param.getName()+", " + param.getValue() + ");");
          }
				request.setAttribute(param.getName(), param.getValue());
			}
		}
	}



【BindingUtil.getValue】
    public static Object getValue(HttpServletRequest request, String name) {
        for (Enumeration names = request.getAttributeNames(); names
                .hasMoreElements();) {
            String reqName = (String) names.nextElement();
            if (reqName.equals(name)) {
                if ("btkOrderId".equals(name)) {     // 特定のパラメータの場合、ログを出力
                    System.out.println("(1)getAttribute:btkOrderId="+ request.getAttribute(reqName));
                    System.out.println("→getParameter:btkOrderId="+ request.getParameter(reqName));
                }
                Object value = request.getAttribute(reqName);
                if (value == null) {
                    return "";
                }
                return value;
            }
        }
        if ("btkOrderId".equals(name)) {    // 特定のパラメータの場合、ログを出力
            System.out.println("(2)getParameter:btkOrderId="+ request.getParameter(name));
        }        
        Object var = request.getParameter(name);
        if (var != null && !JsfConstants.NULL_VALUE.equals(var)) {
            return var;
        }
        if ("btkOrderId".equals(name)) {    // 特定のパラメータの場合、ログを出力
            System.out.println("(3)getAttribute:btkOrderId="+ request.getAttribute(name));
        }   
        var = request.getAttribute(name);
        if (var != null) {
            return var;
        }
        HttpSession session = request.getSession(false);
        if (session != null) {
            var = session.getAttribute(name);
            if (var != null) {
                return var;
            }
        }
        return null;
    }
    
************************************************************************************


ログを埋め込んだ結果は下記の通りとなります。

	request.setAttribute(btkOrderId, 799);
	(1)getAttribute:btkOrderId=799
	→getParameter:btkOrderId=829

これより、一つ前の画面のID(799)が最終的にActionにセットされてしまいます。
これは仕様ということでしょうか。


この上記で述べたように、この画面は自アクションを呼び出すつくりになっておりますが、
自画面の詳細画面を直接指定した場合、正常に動作することは確認しております。
 
この度は、今後のシステムメンテナンスのことを考え、フレームワークの確認という意味で
メールを出させて頂きました。
何卒、宜しくお願い致します。


    


Seasar-user メーリングリストの案内