使用JSP迭代Multimap

sti*_*vlo 5 java jsp jstl guava

我正在尝试编写一个备份仪表板,显示多个服务器备份的状态.我们的想法是显示一个带有JSP的表,其中列中的最后几天日期和行中的服务器名称.在这个穷人的桌子上,我写了是/否值.

+------------+------------+------------+------------+
+ Host Name  | 2011-06-10 | 2011-06-09 | 2011-06-08 |
+------------+------------+------------+------------+
| web01      |     Y      |      Y     |     N      |
+------------+------------+------------+------------+
| web02      |     Y      |      Y     |     Y      |
+------------+------------+------------+------------+
Run Code Online (Sandbox Code Playgroud)

每个服务器都有自己的备份并将状态保存到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);
Run Code Online (Sandbox Code Playgroud)

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}]} 
Run Code Online (Sandbox Code Playgroud)

我不知道如何在JSP中使用这些信息.我试过foreach:

<c:forEach items="${backups}" var="backup" varStatus="backupId">
    ${backup.key}
</c:forEach>
Run Code Online (Sandbox Code Playgroud)

答案是:

javax.servlet.ServletException: javax.servlet.jsp.JspTagException: Don't know 
how to iterate over supplied "items" in <forEach>
Run Code Online (Sandbox Code Playgroud)

现在我在想,如果我用自己太复杂的返回值拍摄自己,我是否应该返回一个简单的HashMap ArrayList,其中每个HashMap包含所有需要的信息(日期,主机名,消息).如果你们认为是一种更好的方法,我没有任何问题来重写提取数据的Java方法,但现在每个单元都需要遍历所有的ArrayList来获取元素(这可能是好的,因为6个服务器由7个天只有42个元素).

你会如何解决这个问题?

Eti*_*veu 9

JSTL forEach标记不支持Multimaps.它只能迭代标准集合/ maps /数组.

当我需要Multimap在JSP中迭代时,我使用它的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>
Run Code Online (Sandbox Code Playgroud)

如果您可以使用JSP EL 2.1,则不需要额外的getter.您只需asMap()在JSP内部调用即可获取Map视图.


所有这些都说,我不确定你Multimap在这里使用的确是什么.一个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>
Run Code Online (Sandbox Code Playgroud)

我不确定这就是你想要的.我想你想要一个Map<String, Map<String, String>>.

另一个解决方案是使用Guava的.