谷本 心 in せろ部屋 このページをアンテナに追加 RSSフィード

2008-02-17

[]MapのvalueはStringで安定。これ豆知識な。

https://ml.seasar.org/archives/mayaa-user/2006-November/000318.html

Strutsでシステム作るなら、MapのvalueはStringにしよう。


StrutsのCheckboxTagクラスでは、引数を文字列として取るから

<html:checkbox name="aaa" property="bbbMap(${ccc})" />

って書いて、cccにIntegerを渡すことができてたとしても

これでは値が取得できない。


たとえば、

ccc」がIntegerの「1」だったとしても

org.apache.struts.taglib.html.CheckboxTagクラスでは

「bbbMap(1)」をまとめて文字列だと解釈するから、

bbbMapからStringの「1」で値を取得しに行って、結果、見つからない。


気をつけろ!


2008/02/24編集

Mapのkeyは・・・というタイトルだったけど、

正しくは、Mapのvalueは・・・でした。

[]なんか、logic:iterateのネストってうまくいかないよね。

Mapを要素に持つBeanをListにして、ActionFormに持たせてみた。


ActionForm -> List<Bean>

Bean -> Map


こういう状態。


ここで、Mapを永続化させようと思って

iterateタグで二重ループを作ったんだけど、うまく行かない。

<logic:iterate id="aaa" name="aaaForm" property="aaaList">
	<html:hidden name="aaa" property="hoge" />
	<logic:iterate id="map" name="aaa" property="bbbMap">
		<html:hidden indexed="true" name="aaa" property="bbbMap(${map.key})" />
	</logic:iterate>
</logic:iterate>

出力されるHTMLは、こんな感じ。indexが期待通りにならない。

<input type="hidden" name="aaa[0].hoge" value="hoge1">
<input type="hidden" name="aaa[0].bbbMap(key1)" value="value1">
<input type="hidden" name="aaa[1].bbbMap(key2)" value="value2">
<input type="hidden" name="aaa[2].bbbMap(key3)" value="value3">

<input type="hidden" name="aaa[1].hoge" value="hoge2">
<input type="hidden" name="aaa[0].bbbMap(key4)" value="value4">
<input type="hidden" name="aaa[1].bbbMap(key5)" value="value5">
<input type="hidden" name="aaa[2].bbbMap(key6)" value="value6">

<input type="hidden" name="aaa[2].hoge" value="hoge2">
<input type="hidden" name="aaa[0].bbbMap(key7)" value="value7">
<input type="hidden" name="aaa[1].bbbMap(key8)" value="value8">
<input type="hidden" name="aaa[2].bbbMap(key9)" value="value9">

こんな風になっちゃう。


期待しているのは、

<input type="hidden" name="aaa[0].hoge" value="hoge1">
<input type="hidden" name="aaa[0].bbbMap(key1)" value="value1">
<input type="hidden" name="aaa[0].bbbMap(key2)" value="value2">
<input type="hidden" name="aaa[0].bbbMap(key3)" value="value3">

<input type="hidden" name="aaa[1].hoge" value="hoge2">
<input type="hidden" name="aaa[1].bbbMap(key4)" value="value4">
<input type="hidden" name="aaa[1].bbbMap(key5)" value="value5">
<input type="hidden" name="aaa[1].bbbMap(key6)" value="value6">

<input type="hidden" name="aaa[2].hoge" value="hoge2">
<input type="hidden" name="aaa[2].bbbMap(key7)" value="value7">
<input type="hidden" name="aaa[2].bbbMap(key8)" value="value8">
<input type="hidden" name="aaa[2].bbbMap(key9)" value="value9">

なんだけど。


子側のiterateのname属性に、親側のiterateのid属性の値を指定しているから、

keyやvalueは正しく取れてるんだけど、要素のindexがおかしくなっちゃう。


内部の実装を見てみると、hiddenタグが自分のindexを取得する際に、

「hiddenタグに一番近い親iterateタグのindex」を探しに行ってる模様。

僕が取りたいのは「hiddenタグのnameの値をidとして持つiterateタグのindex」なんだけど。


logic:iterateって、昔からハマりやすいよね。

とりあえず、logic:iterateとm:forを組み合わせることで、問題を回避しました。


Mayaa使ってない人たちがどうやって回避してるか知らないけど、

logic:iterateとc:forを組み合わせたりするのかな。

2007-12-13

[]クエリ文字列を生成時に、paramName/paramPropertyとnameは一緒に使える。

あう、初めて知ったのでメモ。


<html:link>タグにクエリ文字列を付与したい場合、

単一のプロパティなら、paramId、paramName、paramPropertyを指定して、

複数のプロパティなら、nameとpropertyでMapを指定する、

というのが教科書的なお約束。


で、これ排他利用かと思ってたんだけど、

いま試してみたら、両方同時に使うことができた。


検索条件をMapで、オフセットを単一プロパティで、

それぞれ渡したい時には、便利。


ところで、単一プロパティを複数指定する事ってできないんですかね?

JSFで言うところの、<f:param>みたいなタグ。


、、、ん、

org.apache.struts.taglib.html.ParamTagってのがあるぞ?

何かそれっぽいぞ? 調べてみよう。


(追記)

ビンゴでした。

[]html:paramタグ

Struts1.3.6から追加になったタグらしい。

<html:link ...>
  <html:param name="aaa" value="bbb"/>
  <html:param name="ccc" value="ddd"/>
</html:link>

これでクエリ文字列に、aaa=bbb&ccc=dddが含まれる。

いまのところ、name属性とvalue属性しか定義できず、

<html:link>みたいな高機能さはないらしい(Mapも展開できない)


まぁ、MayaaとかELを使っているなら

paramNameとかparamPropertyとかを指定する方が、

逆に煩わしいぐらいなので、構いませんが。