用JSP迭代Multimap

| 我正在尝试编写一个备份仪表板,以显示多个服务器备份的状态。这个想法是显示一个带有JSP的表,该表的前几天的日期在列中,而服务器名称的行中。在这个可怜的人的桌子上,我写了是/否值。
+------------+------------+------------+------------+
+ Host Name  | 2011-06-10 | 2011-06-09 | 2011-06-08 |
+------------+------------+------------+------------+
| web01      |     Y      |      Y     |     N      |
+------------+------------+------------+------------+
| web02      |     Y      |      Y     |     Y      |
+------------+------------+------------+------------+
每个服务器都进行自己的备份,并将状态保存到Amazon SimpleDb中,我编写了一个Java方法来检索最近几天具有以下签名的信息:
/**
 * List MySQL backups of the last howManyDays days. It starts from today 
 * included at index 0 and goes back in the past until we have a list of 
 * howManyDays days, even if some day doesn\'t have any data. Return a list of 
 * dates, each of which contains a list of backup jobs executed by servers in 
 * that day.
 * 
 * @param howManyDays
 *         how many days of backup to show
 * @return a Map where each key is the date in ISO format (2011-06-10) and each
 *         element is a backupJob which is represented by a Map where the key is 
 *         the server name (ex. web01, web01) and the value is \"Y\" if all was 
 *         fine, otherwise it contains the error message.
 */
public Multimap<String, Map<String, String>> listMysqlBackups(int howManyDays);
Multimap是Google Guava Multimap的一部分,因为我每天要进行多次备份。输出示例:
{2011-06-10=[{web06=Y}, {web05=Y}], 2011-06-08=[{web05=Y}, {web06=Y}], 
 2011-06-09=[{web05=Y}, {web06=Y}], 2011-06-07=[{web05=Y}, {web06=Y}]} 
我不知道如何在JSP中使用此信息。我尝试过foreach:
<c:forEach items=\"${backups}\" var=\"backup\" varStatus=\"backupId\">
    ${backup.key}
</c:forEach>
答案是:
javax.servlet.ServletException: javax.servlet.jsp.JspTagException: Don\'t know 
how to iterate over supplied \"items\" in <forEach>
现在,我在考虑是否要用太复杂的返回值来射击自己,是否应该返回一个简单的HashMap ArrayList,其中每个HashMap都包含所有需要的信息(日期,主机名,消息)。如果你们认为这是一种更好的方法,那么我没有任何问题可以重写Java方法来提取数据,但是现在每个单元都需要遍历所有ArrayList来获取元素(这可以,因为6台服务器通过7天只有42个元素)。 您将如何解决这个问题?     
已邀请:
        JSTL的“ 5”标签不支持“ 6”。它只能遍历标准集合/地图/数组。 当我需要在JSP中遍历
Multimap
时,可以使用其
asMap()
视图。这使我可以使用
forEach
,因为它知道如何在
Map
接口上进行迭代。 它看起来像下面的样子:
public Multimap<String, Map<String, String>> listMysqlBackups(int howManyDays) {
    // ...
}

public Map<String, Collection<Map<String, String>>> getListMysqlBackupsAsMap() {
    return listMysqlBackups(this.numberOfDays).asMap();
}


<c:forEach var=\"backup\" items=\"${bean.listMysqlBackupsAsMap}\">
    <c:set var=\"dateISO\" value=\"${backup.key}/>
    <c:set var=\"backupJobs\" value=\"${backup.value}/> <!-- a Collection<Map<String,String>> -->
    <c:forEach var=\"backupJob\" items=\"${backupJobs}\">
        <!-- do something with each backup job (Map<String, String>) for the current date -->
    </c:forEach>
</c:forEach>
如果可以使用JSP EL 2.1,则不需要其他的吸气剂。您只需在JSP中调用
asMap()
即可获得
Map
视图。 综上所述,我不确定您使用7英镑真的可以满足您的要求。
Multimap<String, Map<String, String>>
将每个键映射到
Map<String,String>
的集合。 就您而言,这意味着您具有:
2011-06-09
    --> Collection
        --> Map<String, String>
        --> Map<String, String>
        --> Map<String, String>
2011-06-10
    --> Collection
        --> Map<String, String>
        --> Map<String, String>
        --> Map<String, String>
我不确定这就是您想要的。我想你要18英镑。 另一种解决方案是使用Guava's Table。     
        只是总结一下我所做的事情,而没有声称是最好的解决方案,所以我回答了我的问题。我很想知道使用Google Table Collection是否可以使事情变得简单。 将listMysqlBackups的返回类型更改为简单的HashMap。
/**
 * List the MySQL backups of the last howManyDays days. It starts from today and 
 * goes back in the past until we have a list of howManyDays days, even if some 
 * day doesn\'t have any data. Return a Map with each index as the ISO date 
 * underscore the server name. Key example: 2011-06-11_web01
 * 
 * @param howManyDays
 *         how many days of backup to show
 * @return a Map where each key is the date in ISO format and each element is
 *         a backupJob which is represented by a Map where the key is the server
 *         name (ex. web01, web01) and the value is \"Y\" if all was fine, 
 *         otherwise it contains the error message.
 */
public Map<String, String> listMysqlBackups(int howManyDays)  
添加了新方法以返回日期列表和服务器列表。
public static List<String> listDatesFromToday(int howManyDays) {
    List<String> dates = new ArrayList<String>();
    String currentDay = DateHelper.getCurrentDateAsIso();
    while (howManyDays > dates.size()) {
        dates.add(currentDay);
        currentDay = DateHelper.previousDay(currentDay);
    }
    return dates;
}

public static List<String> listHosts() {
    return ImmutableList.of(\"web05\", \"web06\");
}
显示带有嵌套循环的表。由于构建密钥的方式,我无需在地图中搜索就可以直接查找密钥。
<table class=\"dataTable\">
    <tr>
    <th></th>
    <c:forEach items=\"${days}\" var=\"day\">
    <th>${day}${host}</th>
    </c:forEach>
    </tr>
<c:forEach items=\"${hosts}\" var=\"host\">
    <tr>
    <th>${host}</th>
    <c:forEach items=\"${days}\" var=\"day\">
    <c:set var=\"key\" value=\"${day}_${host}\"/>
    <td> ${backups[key]}  </td>
    </c:forEach>
    </tr>
</c:forEach>
</table>
我认为该解决方案很简单,对此我很满意,但是如果你们认为Google collection Table可以使代码更简单,简短和简洁,我将很高兴听到。     
        我认为您应该尝试嵌套for循环 例如
<c:forEach items=\"${webs}\" var=\"web\" varStatus=\"webId\">
    <c:forEach items=\"${web.backups}\" var=\"backup\" varStatus=\"backupId\">
        ${backup.key}
    </c:forEach>
</c:forEach>
    

要回复问题请先登录注册