[Seasar-user:2614] Re: [S2JSF]同じページを繰り返し表示する場合の戻るボタンの動作について

Sea Slug seaslug
2005年 9月 27日 (火) 16:35:25 JST


たびたびすみません。竹田です。

1. sessionに保存するviewを現在のページ毎からリクエスト毎に変更する。

の具体的方法について説明します。

- まず、リクエスト毎にrequestIdを生成します。 
  具体的にはorg.seasar.jsf.lifecycle.LifecycleImpl#setupParamsに次の一行を追
加します。
  適当な格納場所がわからなかったのでとりあえずsessionに格納してあります。
  externalContext.getSessionMap().put("requestId", 
String.valueOf(System.currentTimeMillis()));

- HtmlFormRendererをカスタマイズしてリクエスト毎にrequestIdがポストされるよ
うhiddenタグを埋め込みます(カスタマイズ方法は後述)。

- viewをrequestId込みでセッションに保存する変更します。
  具体的には
org.seasar.jsf.application.S2StateManager#saveSerializedViewToSessionを次の
ように
  変更します。
  protected void saveSerializedViewToSession(ExternalContext 
externalContext,
	String viewId, SerializedView serializedView) {
	String requestId = 
(String)externalContext.getSessionMap().get("requestId");
	if (requestId == null){
	    externalContext.getSessionMap().put(
	        SERIALIZED_VIEW_ATTR + "-" + viewId, serializedView);
	} else {
	    externalContext.getSessionMap().put(
	        SERIALIZED_VIEW_ATTR + "-" + viewId + "-" + requestId, 
serializedView);
	}
  }

- requestIdがポストされた場合、requestId込みでviewをセッションから検索するよ
うに変更します。
  具体的には
org.seasar.jsf.application.S2StateManager#getSerializedViewFromSessionを次の
ように
  変更します。
  protected SerializedView getSerializedViewFromSession(
	ExternalContext externalContext, String viewId) {
	String requestId = 
(String)externalContext.getRequestParameterMap().get("requestId");
	if (requestId == null){
	   return (SerializedView) externalContext.getSessionMap().get(
		SERIALIZED_VIEW_ATTR + "-" + viewId);
	} else {
	   return (SerializedView) externalContext.getSessionMap().get(
		SERIALIZED_VIEW_ATTR + "-" + viewId + "-" + requestId);
	}
  }

これでリクエスト毎にviewがセッションに保存されるようになります。

以下、本題から外れますが、HtmlFormRendererのカスタマイズ方法について説明しま
す。
試行錯誤で行ったので正しくないかもしれませんし、もっと簡単な方法があるかもし
れません。
とりあえず、私のところでは動いているようです。

1. org.seasar.taglib.htmlにHtmlFormTag.javaを追加する。HtmlFormTag.javaの内
容は
   次のとおり。
    public class HtmlFormTag extends HtmlFormTagBase {
        private static final String RENDERER_TYPE = "org.seasar.jsf.Form"; 
        public String getComponentType() {
            return HtmlForm.COMPONENT_TYPE;
        }
        public String getRendererType() {
            return RENDERER_TYPE;
        }
    }
2. META-INF/s2jsf.tldに以下のformタグのエントリを追加する。
    <tag>
        <name>form</name>
        <tag-class>org.seasar.jsf.taglib.html.HtmlFormTag</tag-class>
        <body-content>JSP</body-content>
        <description>
            Renders a HTML form element.
        </description>
        <attribute>
            <name>id</name>
            <required>false</required>
            <rtexprvalue>false</rtexprvalue>
            <type>java.lang.String</type>
            <description>Every component may have an unique id. 
Automatically created if omitted.</description>
        </attribute>
        ...このほか、オリジナルのformタグの定義からかき集めたattributeたくさ
ん
    </tag>

3. org.seasar.component.htmlにHtmlForm.javaを追加。HtmlForm.javaの内容は次の
とおり。
    public class HtmlForm extends javax.faces.component.html.HtmlForm  {
        public static final String COMPONENT_TYPE = "javax.faces.HtmlForm";
        public static final String COMPONENT_FAMILY = "javax.faces.Form";
        public static final String DEFAULT_RENDERER_TYPE = 
"org.seasar.jsf.Form";
    
        public String getFamily() {
            return COMPONENT_FAMILY;
        }
        public String getRendererType() {
            return super.getRendererType();
        }
    }

4. org.seasar.renderer.htmlにHtmlFormRenderer.javaを追加。内容は次のとおり。

    public class HtmlFormRenderer extends HtmlFormRendererBase {
        private static final String HIDDEN_REQUEST_ID_INPUT_SUFFIX = 
"requestId";
        public void encodeEnd(FacesContext facesContext, UIComponent 
component)
            throws IOException {
            String requestId = 
(String)facesContext.getExternalContext().getSessionMap().get("requestId");
            if (requestId != null){
                ResponseWriter writer = facesContext.getResponseWriter();
                writer.startElement(HTML.INPUT_ELEM, null);
                writer.writeAttribute(HTML.TYPE_ATTR, "hidden", null);
                writer.writeAttribute(HTML.NAME_ATTR, 
HIDDEN_REQUEST_ID_INPUT_SUFFIX, null);
                writer.writeAttribute(HTML.VALUE_ATTR, requestId, null);
                writer.endElement(HTML.INPUT_ELEM);
            }
            super.encodeEnd(facesContext, component);
        }
    }

5. META-INF/face-config.xmlに以下のcomponentとrendererのエントリを追加。
    <component>
        <component-type>
          	org.seasar.jsf.Form
        </component-type>
        <component-class>
      	org.seasar.jsf.component.html.HtmlForm
        </component-class>
    </component>

    <renderer>
        <component-family>javax.faces.Form</component-family>
        <renderer-type>org.seasar.jsf.Form</renderer-type>
        
<renderer-class>org.seasar.jsf.render.html.HtmlFormRenderer</renderer-class>

    </renderer>

6. org.seasar.jsf.selector.FormSelector#getInjectを修正して追加したタグが使
われるようにする。
   変更内容は次のとおり。
    public String getInject() {
       return getS2JsfInject(TAG_NAME);
    }

_________________________________________________________________
無料でメールボックス250MBの 「MSN Hotmail」 
http://promotion.msn.co.jp/hotmail/fortune/input_un.asp 




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