ちなみにバージョンは1.2.9。
マップバックドアクションフォームとは、アクションフォームBeanの各属性をMapに保存させる方法で、
Mapとそのアクセッサメソッドの定義だけで済み省略化が可能。
よって、Formクラスは単純で済む。ただ、JSPの方ではちょっとだけ特殊な記述になる。
具体的には、
<html:text property="value(attribute)" value="hoge" />
といった具合にpropertyを指定する。
(この例はFormのMapへのアクセッサメソッドが、setValue, getValueで定義している場合)
そうすることにより、setValue(String key, Object value)に、
key=attribute value=hogeで渡される。
この場合は特に問題がないのだけど、チェックボックスや、複数選択可能なセレクトボックスの場合に変な問題が起きた。
チェックボックスの場合で例を挙げると、まず以下のようなソースだった場合、
<logic:iterate id="hoge_id" name="hoge_list" indexId="index">
<html:multibox property='<%= "value(attribute)[" + index + "]" %>'
value="<%= hoge_id.toString() %>" errorStyleClass="input-error" ></html:multibox>
<bean:write name="hoge_id" />
</logic:iterate>
HTML化すると以下のようになる。
<input type="checkbox" name="value(attribute)[0]" value="hoge" >
hoge
<input type="checkbox" name="value(attribute)[1]" value="hoge2" >
hoge2
<input type="checkbox" name="value(attribute)[2]" value="hoge3">
hoge3
そして、SubmitされるとsetValueが配列分コールされるという仕組み。あとはそれらをListなりに突っ込んで処理するという流れだ。
でも、ここで問題がおきた。
java.lang.NoSuchMethodException: Property 'value' has no getter method
というエラーが発生したのだ。いくら調べても分からない。
しかも、実際に似たようなことをやっている箇所があって、そこはうまく動作していた。
でも、よーく、見比べてみるとちょっとだけ違いがあった。そして、以下のように書き直した。
<logic:iterate id="hoge_id" name="hoge_list" indexId="index">
<html:multibox property='<%= "value(attribute)[" + index + " ]" %>'
value="<%= hoge_id.toString() %>" errorStyleClass="input-error" ></html:multibox>
<bean:write name="hoge_id" />
</logic:iterate>
最初のものとどこが違うか分かるだろうか?
'<%= "value(attribute)[" + index + "]" %>'
↓
'<%= "value(attribute)[" + index + " ]" %>'
違いは、]の前に半角スペースがあるだけ。ちなみに生成されたHTMLは以下のようになる。
<input type="checkbox" name="value(attribute)[0 ]" value="hoge">
hoge
<input type="checkbox" name="value(attribute)[1 ]" value="hoge2">
hoge2
<input type="checkbox" name="value(attribute)[2 ]" value="hoge3">
hoge3
こうすることによって、正常に動作するようになった。
安定版と言われている、Struts1.2.9のバグなのか、WEBコンテナ(Tomcat6.0.18)のバグなのか詳しくは調べていないけど、釈然としない問題だった。