JSF 1.2 - iterate over a Map that contains Collections

心不动则不痛 提交于 2019-12-01 15:51:46

问题


Using JSF 1.2 and JSP....

Is it possible to iterate over a Map whose values contain Collections?

I have a Map that looks like this:

Map<String, List<Foo>> myMap;

I would like to iterate over myMap and draw a separate table for each key.

Each table will contaim multiple rows.

Each row will represent a Foo object from the ArrayList mapped to the current key.

Sadly we are using JSF 1.2 and JSP.

I was hoping I could use a nested <h:dataTable> tag, but I'm not having any success.


Edit:

Here is my current JSP code after consulting BalusC's answer:

                    <c:forEach items="#{someModule$someBean.prefMap}" var="mapEntry">
                        <br/><br/><p>Key: <h:outputText value="#{mapEntry.key}"/></p>
                        <h:dataTable value="#{mapEntry.value}" var="pref">
                            <h:column><h:outputText value="#{pref.defaultFieldLabel}"/></h:column>
                            <h:column><h:outputText value="#{pref.fieldLabel}"/></h:column>
                        </h:dataTable>
                    </c:forEach>

It causes the following exception:

javax.servlet.jsp.JspTagException: Don't know how to iterate over supplied "items" in <forEach>


Here is some code from my Managed Bean.

Note that I'm using HashMap and ArrayList instead of Map and List

(I read somewhere you couldn't use interfaces, which also don't work)

private HashMap<String, ArrayList<Foo>> prefMap;

public HashMap<String, ArrayList<Foo>> getPrefMap()
{
  if (prefMap == null)
  {
    buildPrefMap();
  }
  return prefMap;
}

private void buildPrefMap()
{
  prefMap = new HashMap<String, ArrayList<Foo>>();
  for (Foo mdp : getFooArray())
  {
    String cat = mdp.getField().getCategory();
    if (! prefMap.containsKey(cat))
    {
      ArrayList<Foo> mpl = new ArrayList<Foo>();
      mpl.add(mdp);
      prefMap.put(cat, mpl);
    }
    else
    {
      prefMap.get(cat).add(mdp);
    }
  }
}

private void dumpMapInfo()
{
  StringBuilder sb = new StringBuilder();
  Map<String, ArrayList<Foo>> theMap = getPrefMap();
  for (String key : theMap.keySet())
  {
    sb.append(key + ": " + theMap.get(key).size());
  }
  System.out.println("\n\n" + sb.toString());
}

Calling dumpMapInfo before rendering the page confirms that the Map is not null and is populated as expected.


回答1:


JSF doesn't have any component which can iterate over a Map. Only the JSTL <c:forEach> can iterate over a Map. Each iteration gives you a Map.Entry back which in turn has getKey() and getValue() methods. You can in turn use a <h:dataTable> to iterate over the map value.

<c:forEach items="#{bean.map}" var="entry">
    <p>Key: <h:outputText value="#{entry.key}" /></p>
    <h:dataTable value="#{entry.value}" var="foo">
        <h:column><h:outputText value="#{foo.prop1}" /></h:column>
        <h:column><h:outputText value="#{foo.prop2}" /></h:column>
        <h:column><h:outputText value="#{foo.prop3}" /></h:column>
    </h:dataTable>
</c:forEach>

Update this works only when you're using JSTL 1.2. This fails in JSTL 1.1 because #{} is not recognized in JSTL 1.1 tags and hence you're forced to use ${}, but this in turn fails in the nested JSF components because they accept #{} only. You'd basically need to fall back to "plain" JSP/HTML in that entire piece of code, or, better, grab Tomahawk's <t:dataList>.



来源:https://stackoverflow.com/questions/12697519/jsf-1-2-iterate-over-a-map-that-contains-collections

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!