在Spring WebFlow 2.0的jsp中显示信息消息

时间:2011-12-14 13:15:28

标签: java jsp spring-webflow

我有一个包含所选主题列表的模型。每个主题都可以在一个房间内呈现,并且有更多的房间需要根据可用性进行选择。用户可以设置首选空间进行展示。如果它不可用,但其他一些可用,则在选定的时间应该有一条信息消息,表明房间已更改。类似于:

<form:errors path="selectedTopics[${loop.index}].room" />

loop是c:foreach标签中的varStatus属性
我将消息添加到messageContext,如下所示:

MessageContext messages = context.getMessageContext();
String source= "selectedTopics[" + i + "].room";
messages.addMessage(new MessageBuilder().info()
          .source(source)
          .code("topic.room.changed")
          .build());

如果我将错误标记添加为错误,则错误标记有效,但它们不是错误。有没有什么方法可以像错误那样以优雅的方式显示这些信息?

1 个答案:

答案 0 :(得分:5)

DefaultMessageContext我看到所有消息都有一个getter,它在消息上下文中给出了一组消息,而不是通过循环遍历数组,我可以找到当前正在渲染的字段的消息:

<c:forEach var="topic" items="${model.selectedTopics}" varStatus="loop">
    //omitted displaying of topic details
  <c:forEach items="${flowRequestContext.messageContext.allMessages}" var="message">
    <c:set var="msgSrc" value="selectedTopics[${loop.index}].room"></c:set>
    <c:if test="${message.source eq msgSrc}">
        <c:if test="${message.severity eq 'INFO'}">
            <span class="infoText">${message.text}</span>
        </c:if>
     </c:if>
  </c:forEach>
</c:forEach>

但是这样对所有消息的迭代都是针对每个必须渲染的字段完成的,如果你有很多字段,这可能会很慢。

另一种可以实现的方法是获取消息上下文中的消息映射。以下是jsp中输出的上下文示例,我使用了$ {flowRequestContext.messageContext}:

[DefaultMessageContext@2de69e99 sourceMessages = map[[null] -> list[[empty]], 'selectedTopics[2].room' -> list[[Message@12329bcb source = 'selectedTopics[2].room', severity = INFO, text = 'Room changed from ALU1-M1 to ALU1-M2']], 'selectedTopics[4].room' -> list[[Message@87abf31 source = 'selectedTopics[4].room', severity = INFO, text = 'Room changed from ALU1-M1 to ALU2-M1']]]] 

有一个地图 sourceMessages ,用于保存可以使用源作为键检索的字段的所有消息。但问题是在实现org.springframework.binding.message.DefaultMessageContext中没有地图的getter。但是,有一个方法getMessagesBySource(java.lang.Object source),它为指定的源提供一组消息。所以我们可以在EL表达式中使用它。

重要!在EL中传递方法参数仅由EL 2.2中支持的EL规范。默认情况下,EL 2.2在Servlet 3.0 / JSP 2.2容器中提供。请参阅JSTL or JSP 2.0 EL for getter with argument

所以现在信息可以显示:

<c:forEach var="message" items="${flowRequestContext.messageContext.getMessagesBySource(msgSrc)}">
    <c:if test="${message.severity eq 'INFO'}">
        <span class="info">${message.text}</span></td>
    </c:if>
</c:forEach>

如果您需要使用以前的版本而不是Servlet 3.0 / JSP 2.2容器,那么最好的方法是重建sourceMessages映射并在渲染视图之前将其插入flashScope。