Strutsで表形式データ(request)の表示と登録を行う(java)
Strutsで表形式のデータの表示や登録を行う場合,利用するActionのstruts-configが「scope="request"」だった場合,思うようにいかないですよね。
あちこち,ネットを調べてみたんですが,なかなか「これだ!」みたいのが無いので,デバッグしながらちょっと調べてみた結果,次のようにすればいいんじゃないかと思いました。
まず,ActionFormは,次の様に普通なってますよね。(リスト部分)
public List list = new ArrayList();
public List getList() {
return list;
}
public void setList(List list) {
this.list = list;
}
そして,listに入るエンティティのクラスに次の様なものがあるとします。
public class TestListEntity implements Serializable {
public String value1 = "";
public String value2 = "";
public String getValue1() {
return value1;
}
public void setValue1(String value1) {
this.value1 = value1;
}
public String getValue2() {
return value2;
}
public void setValue2(String value2) {
this.value2 = value2;
}
}
sessionならば,もうこれで何もする必要はないのですが,requestで利用すると,listのカウントやエンティティとなるオブジェクトの種類が不明です。
従って,ActionFormのメソッドresetを実装して,次のように初期化するメソッドを書いてみます。
public void reset(ActionMapping mapping, HttpServletRequest request) {
super.reset(mapping, request);
//リストの初期化
int count = Tool.toInt(request.getParameter("list_count"));
for (int i=0; i<count ; i++) {
list.add(new TestListEntity());
}
}
ポイントとなるのは,list_countですが,これは,Actionがresponseする際,listの件数をページ上にhiddenで載せるようにします。
戻るときは,この値をgetParameterして,リストを再構築するわけです。
応用編として,行追加ですが,面倒な場合は,submitしてlistの行数を増やしてしまえばいいのですが,画面がフラッシュするのを嫌う人は多いことでしょう。その場合は,JavaScriptで行を増やす時に,現在の表の件数をこのlist_countにセットすることを忘れなければ,この方式で利用することができます。
この方法で,たとえ,struts-configが,
<action-mappings>
<action ・・・
scope="request"
となっていても,問題なく新規行も含め自動的にstrutsがセットしてくれます。
なお,jsp側は,インデックスを付け忘れないようにしてください。JavaScriptで行を増やしたりコピーしたりする場合は,ここが一番苦労するでしょう。なぜなら,すべてのフィールド名は,list[index].value1 の様な形式だから,index部分を採番する必要があるでしょうから,僕はsubmitする事にしています。
<logic:iterate id="list" name="XXXXXXForm" property="list" type="TestListEntity" scope="request" indexId="index">
<html :text name="list" property="value1" indexed="true"/>
jspでのポイントは,iterate のID と 各フィールドの<html :text name="list" ・・・> は,ActionFormのフィールド名にばっちりあわせなければなりません。 つまり iterate の id="list" と property="list" は同じ名前にする必要があります。
さあ,これでrequestによるStrutsの表データのやりとりはsessionと同じように利用することができるようになりました。今のところ,この方法でうまくいくようですが,みなさんはどの様にされているのでしょうか?
scope="session"にすれは,いいじゃん みたいな乱暴なサイトもありましたが,実際タブブラウザなどになると,なにかとsessionは問題を引き起こしますよね。
ご指摘などお待ちしております。