Nested Properties - Indexed Property と Bean

Strutsメーリングリストで書いた"ビーンをプロパティにして、Indexedプロパティを使う方法"ですが、あれは"Nested Property"っていうんですって。 Indexed PropertyのプロパティがintとかStringとかのプリミティブじゃなくて、beanを使ってhierarchyにするからNested Property。
で、そのサンプルを書こうかな、と。 そもそも何でそんなものがいるかと言うと、ダイナミックなフォームを作るためです。 ここで言う"ダイナミック"は、DynaActionFormとは関係なくて、ランタイムにフォームのプロパティの数が決まる、そういうのです。
とりあえず、見ていきましょう! シナリオは、名前(名フィールドと姓フィールドのペア)リストの入力フォームがあって、ダイナミックに名前が5つになったり10個になったりするとします。 (←相変わらずワカラン説明…)。 とりあえず、プロパティの数が決まっていないので、普通のActionFormで"firstName1, firstName2, ... , lastName1, lastName2, ..."何てことはできないんです。 そこでIndexed Propertyが登場するんですね。長くなるんでコードは書きませんけど、NameBeanというBeanがあって、firstとlast(どちらもString)、それぞれの getter,setterがあるとします。
ActionForm:


//コメントで指摘されて思い出したんですけど、このクラスはインコンプリートです。
//次の日のListUtilsのと一緒に見てくださいね。

import org.apache.struts.action.ActionForm;
import izu.beans.NameBean;
import java.util.List;
import java.util.ArrayList;

public class NameListForm extends ActionForm {
private List nameList;

public NameListForm() {
reset();
}

public void reset() { //[追記] reset()の使い方[3/16/04]参照((これはreset()メソッド内で処理するべきではない。))。
//ここ、本番はDBとかから設定します。
nameList.add(new NameBean("Izumi", "Kamitani"));
nameList.add(new NameBean("Nadim", "Bitar"));
nameList.add(new NameBean("First", "Last"));
}

public void setNameList(List nameList) {
this.nameList = nameList;
}

public List getNameList() {
return nameList;
}

//このメソッドがStrutsがフォームをポピュレートする時に
//重要な役割を果たします。
public NameBean getName(int index) {
return (NameBean) nameList.get(index);
}
}

JSPではを使います。

<html:form action="/name/submit">
<logic:iterate id="name" name="nameListForm" property="nameList">
名: <html:text name="name" property="first" indexed="true" />
姓: <html:text name="name" property="last" indexed="true" /><br/>
</logic:iterate>

<html:submit>Submit</html:submit>
</html:form>

この"indexed"がミソなんですね。でき上がったhtmlはこんな感じになります。

<form name="nameListForm" method="post" action="/appName/name/submit.do">
名: <input type="text" name="name[0].first" value="Izumi">
姓: <input type="text" name="name[0].last" value="Kamitani">

名: <input type="text" name="name[1].first" value="Nadim">
姓: <input type="text" name="name[1].last" value="Bitar">

名: <input type="text" name="name[2].first" value="First">
姓: <input type="text" name="name[2].last" value="Last">

<input type="submit" value="Submit">
</form>

で、実際に送信ボタンを押すと、Strutsが上のリクエストを見て、次のように解釈してくれるわけです。

nameListForm.getName(0).setFirst(Izumi)

えっと…、何か説明し忘れてます? 終わってしまったんですが…。 マッピングは普通と何ら変わりないし、アクションもすることによるわけでこれと言って書くことはないし、と。 そう、結構簡単なんですよね(^^;) 何か抜けてたらコメント↓プリーズ。