Hatena::ブログ(Diary)

i-takehiroの日記 このページをアンテナに追加 RSSフィード

2008-04-24

SAStruts + Velocity (2)

| 08:52 |  SAStruts + Velocity (2)を含むブックマーク  SAStruts + Velocity (2)のブックマークコメント

SAStruts + Velocity が動くことが確認出来たので、今度はSAStruts

チュートリアルに含まれるサンプルをVelocityに移植中です。

そこで、移植にちょっと手間取ったサンプルがありました。

「複数選択リスト」サンプルにて

「複数選択リスト」サンプルのJSPファイルは以下のようになっています。

multiselect.jsp
<html>
<head>
<title>Multiselect</title>
</head>
<body>
<html:errors/>
<s:form action="/multiselect">
<html:select property="select" multiple="true" size="3">
<html:option value="1">One</html:option>
<html:option value="2">Two</html:option>
<html:option value="3">Three</html:option>
</html:select>
<br />
${f:h(select)}<br />
<input type="submit" name="submit" value="サブミット"/>
</s:form>
</body>
</html>

まず、toolbox.xml に ListTool の定義を追加します。

toolbox.xml
 <tool>
   <key>list</key>
   <scope>application</scope>
   <class>org.apache.velocity.tools.generic.ListTool</class>
 </tool>

そして、multiselect.jspを元に、vmファイルを以下のように作成しました。

multiselect.vm
<html>
<head>
<title>Multiselect</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<form name="multiselectActionForm" method="post" action="$link.setRelative("velocity/multiselect/")">
<select name="select" multiple="multiple" size="3">
<option value="1"#if($list.contains($select, "1")) selected="selected" #end>One</option>
<option value="2"#if($list.contains($select, "2")) selected="selected" #end>Two</option>
<option value="3"#if($list.contains($select, "3")) selected="selected" #end>Three</option>
</select>
<br />
$!escape.html($!select)<br />
<input type="submit" name="submit" value="サブミット"/>
</form>
</body>
</html>

すると、以下のようなエラーが発生しました。*1

nvocation of method 'contains' in class org.seasar.struts.action.ArrayWrapper threw exception class java.lang.UnsupportedOperationException : contains

何でだろうと思い、ArrayWrapper#contains(Object)の実装を見てみたら、以下のようになっていました。

    public boolean contains(Object o) {
        throw new UnsupportedOperationException("contains");
    }

これが原因です。

どうしようかな…、ArrayWrapper#toArray()はサポートされていたので以下のように修正してみました。

修正後の multiselect.vm
<html>
<head>
<title>Multiselect</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<form name="multiselectActionForm" method="post" action="$link.setRelative("velocity/multiselect/")">
<select name="select" multiple="multiple" size="3">
<option value="1"#if($list.contains($select.toArray(), "1")) selected="selected" #end>One</option>
<option value="2"#if($list.contains($select.toArray(), "2")) selected="selected" #end>Two</option>
<option value="3"#if($list.contains($select.toArray(), "3")) selected="selected" #end>Three</option>
</select>
<br />
$!escape.html($!select)<br />
<input type="submit" name="submit" value="サブミット"/>
</form>
</body>
</html>

不恰好なコードですが、とりあえず動きました。

もっとスマートな方法は無いのでしょうか?

*1:SAStruts1.0.2-rc3 では、ArrayWrapper#contains(Object) がサポートされる予定になっています

higayasuohigayasuo 2008/04/24 11:18 https://www.seasar.org/issues/browse/SASTRUTS-36
でArrayWrapper#contains()をサポートしました。

morningmist7morningmist7 2008/04/24 11:40 ブログ開設おめでとうございます。雑記でもなんでも書いちゃいましょう(w
Velocityですが、私は以前VelocityLayoutServletを使っていました。とりあえずLayout機能が付いているので重宝しました。

i-takehiroi-takehiro 2008/04/25 11:21 >higayasuo さん
迅速な対応感謝致します。
これでスマートなコードが書けますね。

i-takehiroi-takehiro 2008/04/25 11:23 >morningmist7 さん
ありがとうございます。まだブログ初心者ですが、色々書いて行こうと思います。
不勉強で VelocityLayoutServlet はまだ使ったことがありませんでした。
早速試しに使ってみたいと思います。

トラックバック - http://d.hatena.ne.jp/i-takehiro/20080424/1208994730