kuniku’s diary

はてなダイアリーから移行(旧 d.hatena.ne.jp/kuniku/)、表示がおかしな箇所はコメントをお願いします。記載されている内容は日付およびバージョンに注意してください。直近1年以上前は古い情報の可能性が高くなります。

S2StrutsのPOJOFormのreset()メソッドについて

有名な
忘れっぽいエンジニアのJakarta Strutsリファレンス
http://struts.wasureppoi.com/taglib/02_checkbox.html
のように、

※チェックされた状態から、チェックを外してsubmitしても、チェックしてない状態は
サーバーへ送信されないので、アクションフォームのプパティ値は、"on"または、
"true"の状態のままになっています。
その為、アクションフォームのリセットメソッドを実装して、
リクエストを送信するごとにアクションフォームの値を初期化する必要があります。

リセットしないといけないから、
https://www.seasar.org/issues/browse/STRUTS-50
の通り、1.3.0-RC2で対応済み ってことは
S2Strtus1.2でも動作するのでは?と思ってやってみた。

なお、1.3のドキュメントではreset()について記述があります。

POJOActionForm
resetメソッド
次のシグネチャのメソッドが定義されている場合、ActionFormに値が設定される前に呼び出されます。
SessionスコープのActionFormを使う場合で、プロパティのリセットが必要な場合に使用してください。
public void reset();

S2struts1.2でPOJOFormのreset()をやってみた

以下を参考などにしてみて
http://d.hatena.ne.jp/n-ichimura/20060324/1143218254
http://d.hatena.ne.jp/cero-t/20070524/1180028780

POJOFormのスコープはセッション管理で
画面の初期表示時にチェックボックスをチェックした状態にしたい場合

reset()で、チェックボックスのプロパティをonにして初期値として登録して、
jsp側で、そのプロパティを参照して初期画面ではチェックされた状態とする
ようにしていたけど、これだと チェックを外してsubmitすると、動きがよくない。

submitしてActionのメソッドが呼ばれた場合に、
Actionに定義したPOJOFormのsetterで、POJOFormをセットする前にPOJOFormのreset()が
よばれチェックを外したプロパティがonで復活してしまう。

・・・・これは やり方がよろしくないんでしょう。

reset()は、あくまでも チェックなしの状態にするだけにすべきなんでしょう。

ということで、
Action側でセッション扱いをするPOJOFormの中にダミー用プロパティを用意して、
そのプロパティに値が未設定の場合(=初期表示)と判断して、初期表示用に
チェックボックスをonするように、POJOFormの値を書き換えるようにした。

こうゆうやり方は、なんか苦肉。スマートなやり方ないんかな。
Actionクラスのcomponent定義で

<component name="pojoAction" instance="request" 
                             class="xxx.PojoActionImpl">
 <initMethod name="initialize"/>
</component>

として、init時に、初期化値を入れたりするほうがよいのかな。

以下、PojoFormとActionクラス(actionの実行時に、初期化するか判別している)

public class PojoForm{
   
   private String dummy;
   private String chkboxHuman;
   //setter,getter略
   public void reset(){
	//最初は、ここで初期値をセットしていたが、
	//ここではリセット(チェックなし)するのみとすべき?
    this.chkboxHuman = "on";
  }
}

public class PojoActionImpl implements  PojoAction{
    private PojoForm pojoForm;
	public void setPojoForm(PojoForm pojoForm){
       this.pojoForm=pojoForm;
    }
  
    @ExportToSession
    public PojoForm getPojoForm(){
	return pojoForm;
    }
    public void execute(){
	if (this.pojoForm == null || this.pojoForm.getDummy){
         	//ここで初期値のチェックありにすべき?
	    pojoForm.setchkboxHuman("on");
	}
        //なんらかの処理を実行・・・
    }
}


2008-12-04 14:00追記

id:skimuraさんのコメントの以下ドキュメントのように
http://s2struts.seasar.org/ja/1.2/s2struts.html#TagLibCheckbox

<s2struts:checkbox property="chkboxHuman"></s2struts:checkbox>

とすれば、reset()メソッドを呼び出す必要がなくなります。

A.画面表示(チェックなし)→B.チェックを入れる→C.subimit→D.画面表示(チェックが自動的に付加)
表示後の画面で、E.チェックを外す→F.submit→G.画面表示(チェックが消える)
という流れにおいて、

<html:checkbox property="chkboxHuman" ></html:checkbox>

のように、strutsのcheckboxを利用している場合は、
C〜DまたはF〜Gの間のサーバ側の処理においてActionFormのresetメソッドを呼び出すが、
s2strutsのTagLibCheckboxを使用すると、resetメソッドを呼び出さなくてもよいみたい。

と思う。もうちょっと調査してみよう。


2008-12-13 21:00追記
チェックボックスに限らずに、プロパティを選択していない場合にリクエストが
何も送られて来ないものとして、複数選択のリストもある。

選択状態→選択を外す→submit

とした時に、未選択はリクエストにないから、reset()メソッド内で、

    private String[] bar;
    ...
    public void reset() {
        foo = false;
        bar = new String[0];
    }

みたいに、barを選択なしにする必要がある。
ちなみに、上記で扱ってるのは、S2Strutsだけど、選択リストの場合にも
reset()メソッドを使うのは、SAStrutsのドキュメントを見て知った。