Отображение информационных сообщений в jsp для Spring WebFlow 2.0 - PullRequest
6 голосов
/ 14 декабря 2011

У меня есть модель со списком выбранных тем.Каждая тема может быть представлена ​​в комнате, и есть больше комнат, которые нужно выбирать в зависимости от наличия.Пользователь может установить предпочтительную комнату для представления.Если он недоступен, но доступно другое, в выбранное время должно появиться информационное сообщение об изменении комнаты.Что-то вроде цикла:

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

является атрибутом varStatus в теге c: foreach Я добавляю сообщения в messageContext следующим образом:

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

Тег ошибки работает, если я добавляю их как ошибки, но они не являются ошибками.Есть ли способ, которым я могу отображать эти информационные сообщения в элегантном виде, как ошибки?

1 Ответ

5 голосов
/ 15 декабря 2011

Из DefaultMessageContext Я видел, что есть геттер для всех сообщений, который дает массив сообщений в контексте сообщения, и, перебирая массив, я могу найти сообщения для поля, которое является в настоящее время рендеринг:

<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 нет метода получения карты. Однако есть метод getMessagesBySource (java.lang.Object source), который выдает массив сообщений для указанного источника. Таким образом, мы можем использовать это в выражении EL.

ВАЖНО! Передача аргументов метода в EL возможна только в спецификации EL, поддерживаемой в EL 2.2. EL 2.2 по умолчанию поставляется в контейнерах Servlet 3.0 / JSP 2.2. См. JSTL или JSP 2.0 EL для получения с аргументом

Так что теперь информация может отображаться с помощью:

<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 перед рендерингом представления.

...