简体   繁体   中英

Render multi value hash map with single key and multiple values in JSP

I have the following MultiHashMap in the controller.java

MultiHashMap multimap= new MultiHashMap();

List<SampleList> list1 = (List<SampleList>) 
                         request.getPortletSession().getAttribute("list1");  
Iterator<SampleList> sampleListIterator= list1.iterator();

while(sampleListIterator.hasNext()){
    SampleList sampleList = sampleListIterator.next();
    List <SubList> subList =  sampleList.getsubList();
    Iterator<SubList> subListIterator = subList.iterator();

    while(subListIterator.hasNext() ){
        SubList subList2 = subListIterator.next();
        multimap.put(subList2.getCategorySubcategory(),subList2.getCost());
    }
}

In the jsp I have a table which displays the above hashmap

<table>
    <tbody>
        <c:foreach var="item" items="${multimap}">
            <tr>
                <th> ${item.key}</th>
                <c:foreach var="valueList" items=${item.value}>
                    <td> ${valueList}</td>
                </c:foreach>
            </tr>
        </c:foreach>
    </tbody>
</table>

I'm getting an error when I try to render the value from the controller.

Apache Commons MultiHashMap is deprecated , you should use instead MultiValueMap .

Deprecated . Class now available as MultiValueMap in map subpackage. This version is due to be removed in collections v4.0.

Both the MultiHashMap and MultiValueMap classes have a getCollection(Object key) method, that will return a Collection of values for that specific key :

 java.util.Collection getCollection(java.lang.Object key) 

Gets the collection mapped to the specified key.

You can iterate it in JSP as any other Collection, by using JSTL, OGNL, etc...


EDIT

Surprinsingly, there is not even one example of this Class usage in JSTL nor OGNL in the whole Internet... I guess your question will become popular, +1 ;)

Since MultiValueMap (and the deprecated MultiHashMap) is a Map with a Collection of values for every key of the Map, it should be iterated in JSTL like this (untested, but presumably right) ( now TESTED on JSTL 1.1.2 in a Servlet 2.4 / JSP 2.0 Container ):

<c:forEach var="entry" items="${multiMap}">
    <br/>-> Key: <c:out value="${entry.key}"/>
    <br/>-> Values for this key:
    <c:forEach var="currentValue" items="${entry.value}">
        <br/>|---> value: <c:out value="${currentValue}"/>
    </c:forEach>
</c:forEach>

Populating it like this

multiMap = new MultiValueMap();
multiMap.put("key1", "value1-1");
multiMap.put("key1", "value1-2");
multiMap.put("key1", "value1-3");
multiMap.put("key2", "value2-1");
multiMap.put("key2", "value2-2");
multiMap.put("key2", "value2-3");
multiMap.put("key3", "value3-1");
multiMap.put("key3", "value3-2");
multiMap.put("key3", "value3-3");

The output is this (copied and pasted from my JSP):

-> Key: key1
-> Values for this key:
|---> value: value1-1
|---> value: value1-2
|---> value: value1-3
-> Key: key3
-> Values for this key:
|---> value: value3-1
|---> value: value3-2
|---> value: value3-3
-> Key: key2
-> Values for this key:
|---> value: value2-1
|---> value: value2-2
|---> value: value2-3 

Then it works perfectly (apart from the curious fact that key3 is coming up before key2); if you still have problems, they're not code-related, but in your config.

Please check out the JSTL tag wiki on SO , this nice article or the numerous answers to JSTL problems from BalusC here on SO.


As a final though, looking at the code you are using to create the MultiValueMap, I strongly suggest you to start building some custom object , as Object Oriented Programming suggests, to avoid excessive nesting of Lists and Maps, that could result in unreadable, unmaintainable code.

I haven't used MultiHashMaps before, but this is how I usually display my HashMap contents in a jsp page (without generics example):

Iterator iter = map.entrySet().iterator();
while(iter.hasNext()){
   Map.Entry entry = iter.next();
   Object key = entry.getKey();
   Object value = entry.getValue();

Using JSTL Core taglibrary: <%

Map<String, String> countryList = new HashMap<String, String>();
countryList.put("United States", "Washington DC");
countryList.put("India", "Delhi");
countryList.put("Germany", "Berlin");
countryList.put("France", "Paris");
countryList.put("Italy", "Rome");

request.setAttribute("capitalList", countryList);
 %>



<c:forEach var="country" items="${capitalList}">
    Country: ${country.key}  - Capital: ${country.value}
</c:forEach>

If you are using struts, then you can struts logic tag library to iterate and display the map in JSP:

 <logic:iterate name="students" id="nameObj" scope="session">
    <bean:write name="nameObj" property="key"/>
    <bean:write name="nameObj" property="value"/>
 </logic:iterate>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM