我正在尝试编写一个备份仪表板来显示多服务器备份的状态。这个想法是用 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 个服务器) days 只有 42 个元素)。
您将如何解决这个问题?
I'm trying to write a backup dashboard showing the status of multiple servers backup. The idea is to show a table with JSP that has the last few days dates in the columns and server names in rows. In this poor man's table I wrote Yes/No values.
+------------+------------+------------+------------+
+ Host Name | 2011-06-10 | 2011-06-09 | 2011-06-08 |
+------------+------------+------------+------------+
| web01 | Y | Y | N |
+------------+------------+------------+------------+
| web02 | Y | Y | Y |
+------------+------------+------------+------------+
Each server, does its own backup and saves the status into Amazon SimpleDb and I wrote a Java method to retrieve this information of the last few days with the following signature:
/**
* 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 is the Google Guava Multimap because I've multiple backups per day. Example output:
{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}]}
I don't know how to consume this information in JSP. I tried with foreach:
<c:forEach items="${backups}" var="backup" varStatus="backupId">
${backup.key}
</c:forEach>
And the answer was:
javax.servlet.ServletException: javax.servlet.jsp.JspTagException: Don't know
how to iterate over supplied "items" in <forEach>
Now I'm thinking if I'm shooting myself in the foot with a too complex return value and whether I should instead return a simple ArrayList of HashMap where each HashMap contains all the needed info (date, hostname, message). If you guys think is a better approach I don't have any problems to rewrite the Java method extracting the data, but each cell will now require to loop across all the ArrayList to get the element (which could be ok because 6 servers by 7 days is only 42 elements).
How would you approach this problem?
发布评论
评论(3)
JSTL
forEach
标记不支持Multimaps
。它只能迭代标准集合/映射/数组。当我需要在 JSP 中迭代
Multimap
时,我使用它的asMap()
视图。这让我可以使用forEach
,因为它知道如何迭代Map
接口。它看起来如下所示:
如果您可以使用 JSP EL 2.1,则不需要额外的 getter。您只需在 JSP 中调用
asMap()
即可获取Map
视图。话虽如此,我不确定您使用的 Multimap 是否真的能达到您想要的效果。
Multimap>
将每个键映射到Map
的集合。就你而言,这意味着你有:
我不确定这就是你想要的。我认为您需要一个
Map>
。另一个解决方案是使用 Guava 的 Table< /a>.
The JSTL
forEach
tag does not supportMultimaps
. It can only iterate over standard collections / maps / arrays.When I need to iterate over a
Multimap
in a JSP, I use itsasMap()
view. This lets me useforEach
, since it knows how to iterate over theMap
interface.It would look like the following:
If you can use JSP EL 2.1, you do not need the additional getter. You can simply call
asMap()
inside the JSP to obtain theMap
view.All this being said, I'm not sure your use of a
Multimap
really does what you want here. AMultimap<String, Map<String, String>>
maps each key to a collection ofMap<String,String>
.In your case, it means that you have:
I'm not sure that's what you want here. I think you want a
Map<String, Map<String, String>>
.Another solution would be to use Guava's Table.
只是为了总结我所做的事情,而不是声称这是我回答我的问题的最佳解决方案。我很想知道使用 google Table 集合是否可以使事情变得更简单。
将 listMysqlBackups 的返回类型更改为简单的 HashMap。
添加了返回日期列表和服务器列表的新方法。
使用嵌套循环显示表。< /strong> 由于我构建密钥的方式,我可以直接查找密钥,而无需在地图中搜索它们。
我认为这个解决方案很简单,我对此很满意,但如果你们认为 Google Collection Table 使代码更简单、更短、更清晰,我会很高兴听到。
Just to summarize what I've done, and without claiming to be the best solution I answer to my question. I'm interested to know if using google Table collection could make things simpler or not.
Changed the return type of listMysqlBackups to a simple HashMap.
Added new methods to return the day list and the server list.
Show the table with a nested loop. I can seek the keys directly without searching them in the Map, because of the way I built the key.
I think this solution is simple, and I'm happy with it, but if you guys think that Google collection Table makes simpler, shorter and cleaner code I'd be happy to hear.
我认为你应该尝试某种嵌套的 for 循环,
例如
I think you should try sort of nested for loop
e.g.