JSF 1.2 with JSP 2.1を使用してc:forEachタグの統一EL式でハッシュテーブルを使用できますか?
質問
ハッシュテーブル<!> lt;整数、スポーツ<!> gt;私のバッキングBeanからsportMapとsportIdのリスト(List <!> lt; Integer <!> gt; sportIds)と呼ばれます。 SportオブジェクトにはList <!> lt; String <!> gt;があります。 equipmentList。ユニファイドELを使用して次のことを実行して、各スポーツの機器のリストを取得できますか?
<h:dataTable value="#{bean.sportIds}" var="_sportId" >
<c:forEach items="#{bean.sportMap[_sportId].equipmentList}" var="_eqp">
<h:outputText value="#{_eqp}"></h:outputText>
<br/>
</c:forEach>
</h:dataTable>
このJSPコードを実行しようとすると、次の例外が発生します。
15:57:59,438 ERROR [ExceptionFilter] exception root cause javax.servlet.ServletException: javax.servlet.jsp.JspTagException: Don't know how to iterate over supplied "items" in <forEach>
ここに私の環境のプリントアウトがあります
Server: JBossWeb/2.0.1.GA Servlet Specification: 2.5 JSP version: 2.1 JSTL version: 1.2 Java Version: 1.5.0_14
注:以下は、JSFタグを使用して機能します。 sportIdsのリストで指定された各スポーツの機器のリストを出力します。
<h:dataTable value="#{bean.sportIds}" var="_sportId" >
<h:outputText value="#{bean.sportMap[_sportId].equipmentList}">
</h:outputText>
</h:dataTable>
c:forEachタグを使用したいと思います。これが可能かどうか誰にもわかりますか?そうでない場合、誰にも提案がありますか?最後に、equipmentList.toString()によって提供されるコンマ区切りリストの代わりに、スタックリストが必要です。 (また、toString()をオーバーライドしたくない)。
解決
JSF 1.2ではTRUEではありません。 java.net wiki faq によると、それらは期待どおりに連携するはずです。 。
各faqからの抜粋:
JSF 1.1 FAQ
Q. JavaServer Facesタグは、JSTLコアタグforEach、if、select、whenと相互運用できますか?A。 forEachタグは、JSTLとJavaServerで使用される戦略の間に互換性がないため、JavaServer Facesテクノロジーバージョン1.0および1.1タグでは機能しません。 Facesテクノロジー。代わりに、独自の反復を実行するdataTableタグで使用されるTableレンダラーなどのレンダラーを使用できます。 if、select、whenタグは機能しますが、これらのタグ内にネストされたJavaServer Facesタグには明示的な識別子が必要です。
この欠点はJSF 1.2で修正されました。
JSF 1.2 FAQ
Q. JavaServer Facesタグは、JSTLコアタグforEach、if、select、whenと相互運用できますか?A。はい。 JSP Id Consumerと呼ばれるJSP 2.1の新機能により、これらのタグは期待どおりに機能します。
特定のJSTLコアタグでJSFタグを使用した人はいますか?
他のヒント
同じ問題が一度発生しましたが、dataTableを使用して解決策を見つけることができませんでした。 問題は、var _sportId がdataTableコンポーネントによってのみ読み取られることです。
ループ内でループを実行する必要がある場合は、dataTable内でdataTableを使用できます。
<h:dataTable value="#{bean.sportIds}" var="_sportId" >
<h:dataTable value="#{bean.sportMap[_sportId].equipmentList}" var="_eqp">
<h:outputText value="#{_eqp}"></h:outputText>
</h:dataTable>
</h:dataTable>
ただし、この場合、各equipmentListアイテムはテーブル行内に印刷されます。私にとって素晴らしい解決策ではありませんでした。
dataTableの代わりに通常のhtmlテーブルを使用することを選択しました:
<table>
<c:forEach items="#{bean.sportIds}" var="_sportId">
<tr>
<td>
<c:forEach items="#{bean.sportMap[_sportId].equipmentList" var="_eqp">
<h:outputText value="#{_eqp} " />
</c:forEach>
</td>
</tr>
</c:forEach>
</table>
動作します。バインディングや行マッピングなどの特定のdataTable機能が必要な場合は、 f:setPropertyActionListener タグを使用して簡単に取得できます。
2つの問題:
- dataTableには、ヘッダーファセット、フッターファセット、列の子のみを含めることができます。それ以外は正しく評価されません。
- JSTLタグをJSFコンポーネントと組み合わせることはできません。 JSTLタグは、コンポーネントツリーが作成されるときに評価されます。 JSFコンポーネントは、ページがレンダリングされるときに評価されます。したがって、c:forEachタグは1回だけ評価されます。コンポーネントツリーが作成されるときは、<!> quot;#{bean.sportIds} <!> quot;の前である可能性があります。利用可能です。
どちらも、あなたが望むループを提供するJSFコンポーネントライブラリを使用するか、あなたが望むループを行うものを構築するか、beanをリファクタリングして、sportIdsをループする代わりに、各スポーツが持つスポーツのリストをループするIDと機器。