Struts2の
ごく簡単なWebアプリケーションを作成する場合ですら、必須のタグであると言って良いです。たぶん。
しかしながら、
落とし穴?
先日の日記では、
実は
main.jsp
<%@ page pageEncoding="UTF-8"%> <%@ taglib uri="/struts-tags" prefix="s"%> <s:set var="hoge" value="1" /> (hoge in main.jsp) = <s:property value="#hoge" /> <%-- <s:component>を使っても結果は同じ --%> <s:include src="./sub.jsp" /> (hoge in main.jsp) = <s:property value="#hoge" />
sub.jsp
<%@ page pageEncoding="UTF-8"%> <%@ taglib uri="/struts-tags" prefix="s"%> <s:iterator var="hoge" value="{1, 2, 3}"> (hoge in sub.jsp) = <s:property value="#hoge" /> </s:iterator>
このとき、main.jspを実行した結果は次の通りです。
(hoge in main.jsp) = 1 (hoge in sub.jsp) = 1 (hoge in sub.jsp) = 2 (hoge in sub.jsp) = 3 (hoge in main.jsp) = 3 ← hogeが3になっている
この通り、変数hogeの値が呼び出し先(sub.jsp)で勝手に書き変わってしまいます。
これは、
この問題は、変数名の付け方に配慮すれば回避できる問題ではありますが、それはそれで以下のような問題もあります。
僕の選んだ解決策
この問題は結局、
これは、Javaで言うと、
for (int i = 0; i < ary.length; i++) { ... }
このコードのループ変数iのスコープがforの内側だけで有効なことと同一です。
これはモダンなプログラミング言語では当たり前ですね。
というわけで、先日作成したカスタムタグを応用して、
ローカル変数のスコープを提供するタグ
次のように使います。
main.jsp
<%@ page pageEncoding="UTF-8"%> <%@ taglib uri="/struts-tags" prefix="s"%> <%@ taglib uri="/r42fw-tags" prefix="r"%> <r:block> <r:set-local var="hoge" value="1" /> (hoge in main.jsp) = <s:property value="#hoge" /> <s:include src="./sub.jsp" /> (hoge in main.jsp) = <s:property value="#hoge" /> </r:block>
sub.jsp
<%@ page pageEncoding="UTF-8"%> <%@ taglib uri="/struts-tags" prefix="s"%> <%@ taglib uri="/r42fw-tags" prefix="r"%> <r:foreach var="hoge" value="{1, 2, 3}"> (hoge in sub.jsp) = <s:property value="#hoge" /> </r:foreach>
このとき、main.jspを実行した結果は次の通りです。
(hoge in main.jsp) = 1 (hoge in sub.jsp) = 1 (hoge in sub.jsp) = 2 (hoge in sub.jsp) = 3 (hoge in main.jsp) = 1
公開してみる
ところで、今回作成した
Sourceforgeにて配布準備中です。公開までしばらくお待ちください。
(追記)
配布開始しました。
SourceForgeでプロジェクトをホストするのは初めてなので少しおかしな部分もあるかもしれませんが、そのうち直します。
(09/07/02 追記)
ファイルの配布については、こちらも参照してください。
http://d.hatena.ne.jp/takahashikzn/20090702