使用JSF、MyFaces和Facelets迭代HashMap时出现问题

3
我遇到了一些问题,无法循环遍历HashMap并将其值打印到屏幕上。请问有谁能够检查我的代码,看看我做错了什么?我似乎找不到任何错误,但肯定有问题。

在一个servlet中,我正在将以下内容添加到请求中:

Map<String, String> facetValues = new HashMap<String, String>();
// Filling the map
req.setAttribute(facetField.getName(), facetValues);

在一个案例中,“facetField.getName()”的返回值为“discipline”。因此,在我的页面上,我有以下内容:
<ui:repeat value="${requestScope.discipline}" var="item">
  <li>Item: <c:out value="${item}"/>, Key: <c:out value="${item.key}"/>, Value: <c:out value="${item.item}"/></li>
</ui:repeat>

循环只运行了一次,但所有输出都是空的?!如果它已经运行了一次,我至少会在item中期望一些东西。检查Facelets的调试弹出窗口,disipline在循环中。将其打印到屏幕上会导致像地图一样的输出(我已经缩短了输出)。
{300=0, 1600=0, 200=0, ... , 2200=0}

我也尝试过使用c:forEach,但结果相同。有没有人知道我做错了什么?感谢任何帮助。 Lee

你能澄清一下吗:你是否在地图中看到了每个项目的“Item:,Key:,Value:”(但实际值没有打印出来)? - mtpettyp
不是针对每个值。循环只执行一次。但我非常确定我将正确的HashMap传递给了循环。 - Lee Theobald
3个回答

12

使用el 2.2支持,您可以像下面这样迭代映射。

<ui:repeat value="#{myBean.stats.keySet().toArray()}" var="x">
    <h:outputText value="#{myBean.stats.get(x)}" /><br />
</ui:repeat>

谢谢你,Berkay,为我省了很多麻烦。 - Thomas Buckley

10

<ui:repeat> 只接受 List 或 DataModel,不支持 Set 或 Map。这在 JSF 2.1 的路线图中有所规划。


1

我有三个想法:

1.

ui:repeat文档没有提到(只提到了List),但我看到UIRepeat使用DataModel作为其模型(像h:dataTable一样)。 Map不会自动包装为DataModel类型-该类型不受隐式支持。 您需要将值使其成为您自己的DataModel实现的实例,或者将它们提供为隐式支持的类型(例如java.util.List)。

2.

我不确定您打算将这些值映射到什么:

${item}
${item.key}
${item.item}

如果你将 "discipline" 更改为类型为 List<Map.Entry<String,String>>,那么你就可以绑定到 key and value 属性:

${item.key}
${item.value}

你可以这样创建列表:

Map<String, String> facetValues = new HashMap<String, String>();
// Filling the map
List<Map.Entry<String, String>> discipline
        = new ArrayList<Map.Entry<String, String>>(facetValues.entrySet());

3.

常见问题解答建议,JSTL标签仅在组件树创建时进行评估。我不确定在ui:repeat的子元素中使用c:out是否能正常工作。您可能需要改用h:outputText。(当然,我可能是错的 - 我还没有尝试过。)


在一个servlet中,我正在将以下内容添加到请求中。
这听起来像是在JSF中将某些东西放入请求范围的奇怪方式,但我会相信你知道自己在做什么!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接