使用“JSF”或JSTL TAGS迭代java.util.Map的问题

时间:2009-09-22 15:58:11

标签: java jsp jsf map jstl

我正在使用Richfaces JSF,我想迭代Map<Object,Object>。我在Sun论坛和其他网站上看到了很多示例,但在我的情况下它不起作用。这是我的XHTML代码:

<c:forEach items="#{order.customOptions}" var="option">
    <h:outputText value="this text does not print" />
    <h:outputText value="#{option.value.name}" />
    <h:outputText value="#{option.value.key}" />
</c:forEach>

“order”对象的类型为Order。 “customOptios”的类型为Map<CustomOption,CustomOptionValue>。当我创建Javascript警报以打印'#{order.customeOptions}'时,其内容是正确的,但它甚至没有输入c:forEach loop

更新1::我尝试了一个列表,但它不起作用。我使用了列表并在其他页面中得到了答案。我也使用a4j:poll和其他一些ajax组件有什么问题吗?

<c:forEach items="#{order.food.cusomableOptions}" var="option">
    <h:outputText value="this text does not print" />
    <h:outputText value="#{option.title}" />
</c:forEach>

更新2:以下是<h:outputText value="#{order.customOptions}" />的输出:

{model.CustomOption@be8464=model.CustomOptionValue@14e8ac9, 
 model.CustomOption@1ea0c8b=model.CustomOptionValue@78f4, 
 model.CustomOption@24389c=model.CustomOptionValue@3f0bc0, 
 model.CustomOption@a765c=model.CustomOptionValue@3b34ca, 
 model.CustomOption@95868c=model.CustomOptionValue@199de59}

更新3:当我在rich:column之外使用它时,它有效, 但是当我在rich:dataTablerich:column标记中使用它时,它不起作用:

<rich:column>
    <f:facet name="header">
        <h:outputText value="xf" />
    </f:facet>
    <c:forEach items="#{order.customOptions}" var="option">
        <p><h:outputText value="option : #{option.key.title}" /></p>
    </c:forEach>
</rich:column>

7 个答案:

答案 0 :(得分:4)

This blog可能会有所帮助,因为在JSF上使用JSTL标记时会出现一些问题。

答案 1 :(得分:3)

如果我需要迭代Map,我使用helper类(例如Entry),如下所示:

public class Entry {
    private String value;
    private String key;

    public Entry(String value, String key) {
        super();
        this.value = value;
        this.key = key;
    }

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}

和将地图转换为List的方法:

private List<Entry> mapToList(Map<String,String> map) {
    List<Entry> list = new ArrayList<Entry>();
    for(String key: map.keySet()) {
        list.add(new Entry(key, map.get(key)));
    }
    return list;        
}

XHTML:

<ui:repeat var="entry" value="#{bean.list}" varStatus="i">
    <div>#{entry.key} : #{entry.value}</div>
</ui:repeat>

也许这会对你有所帮助......或者可能没有;)

答案 2 :(得分:1)

如果甚至没有输入循环,则表示地图只是空的。

您可以通过添加类似

的内容来诊断
<h:outputText value="map size: #{order.customOptions.size()}" />

在循环标记前面,但你应该真的设置一个像eclipse或Netbeans这样的IDE并在其中运行你的代码,以便你可以使用一个真正的调试器 - 你将能够更容易地解决问题,这样更快。

答案 3 :(得分:1)

JSTL和JSF不能无缝地同步工作,因为您可以直观地期望源代码中的排序。粗略地说,JSTL首先从上到下处理整个页面,然后将生成的输出(因此,没有任何JSTL标签,但是使用其生成的输出)交给JSF,后者又处理整个页面从上到下再次。

UIDatah:dataTable之类的JSF rich:dataTable组件在JSTL运行时尚未生成任何行,这表明您不会看到c:forEach中的任何内容在一列内。

要解决此问题,您应该使用JSF提供的迭代组件,例如RichFaces'a4j:repeat,Facelets'ui:repeat或Tomahawk t:dataList。它们都与JSTL c:forEach相同或更多。

对于JSTL标记的残余, functions taglib在JSF中很有用,所有其他taglib在JSF环境中都是超级的,因为它提供了相同的功能。 box(JSTL core和format taglibs),或者它根本不适合MVC思想(JSTL sql和xml taglibs)。

答案 4 :(得分:0)

也许你不应该混合JSTL:核心标签和JSF:h标签。

问候。

答案 5 :(得分:0)

只需将您的MAP转换为ArrayList,然后使用h:dataTable即可解决您的问题。

答案 6 :(得分:0)

您应该使用等效的JSF标记。你试过<a4j:repeat/>吗?