Сообщения о состоянии на сайте Spring MVC (контроллер аннотации)
Каков наилучший способ организации сообщений о статусе ( "Ваши данные были успешно сохранены/добавлены/удалены" ) на сайте Spring MVC с использованием контроллера аннотаций?
Итак, проблема заключается в отправке сообщения из POST-метода в contoller.
Ответы
Ответ 1
Как упоминалось muanis, поскольку spring 3.1, лучшим подходом было бы использование RedirectAttributes. Я добавил i18n к образцу, указанному в блоге. Таким образом, это будет полный образец.
@RequestMapping("/users")
@Controller
public class UsersController {
@Autowired
private MessageSource messageSource;
@RequestMapping(method = RequestMethod.POST, produces = "text/html")
public String create(@Valid User user, BindingResult bindingResult, Model uiModel, HttpServletRequest httpServletRequest, Locale locale, RedirectAttributes redirectAttributes) {
...
...
redirectAttributes.addFlashAttribute("SUCCESS_MESSAGE", messageSource.getMessage("label_user_saved_successfully", new String[] {user.getUserId()}, locale));
return "redirect:/users/" + encodeUrlPathSegment("" + user.getId(), httpServletRequest);
}
...
...
}
Добавьте соответствующее сообщение в свой комплект сообщений, например messages.properties.
label_user_saved_successfully=Successfully saved user: {0}
Измените файл jspx, чтобы использовать соответствующий атрибут
<c:if test="${SUCCESS_MESSAGE != null}">
<div id="status_message">${SUCCESS_MESSAGE}</div>
</c:if>
Ответ 2
Проверенный подход заключается в использовании специальной области флэш-памяти для сообщений, которые должны сохраняться до следующего запроса GET.
Мне нравится использовать Flash-объект с охватом сеанса:
public interface Flash {
void info(String message, Serializable... arguments);
void error(String message, Serializable... arguments);
Map<String, MessageSourceResolvable> getMessages();
void reset();
}
@Component("flash")
@Scope(value = "session", proxyMode = ScopedProxyMode.INTERFACES)
public class FlashImpl implements Flash {
...
}
Специальный перехватчик MVC будет считывать значения вспышки из объекта вспышки и помещать их в область запроса:
public class FlashInterceptor implements WebRequestInterceptor {
@Autowired
private Flash flash;
@Override
public void preHandle(WebRequest request) {
final Map<String, ?> messages = flash.getMessages();
request.setAttribute("flash", messages, RequestAttributes.SCOPE_REQUEST);
for (Map.Entry<String, ?> entry : messages.entrySet()) {
final String key = "flash" + entry.getKey();
request.setAttribute(key, entry.getValue(), RequestAttributes.SCOPE_REQUEST);
}
flash.reset();
}
...
}
Теперь в вашем контроллере вы можете просто размещать сообщения в "области видимости":
@Conteroller
public class ... {
@Autowired
private Flash flash;
@RequestMapping(...)
public void doSomething(...) {
// do some stuff...
flash.info("your.message.key", arg0, arg1, ...);
}
}
По вашему мнению, вы перебираете флэш-сообщения:
<c:forEach var="entry" items="${flash}">
<div class="flash" id="flash-${entry.key}">
<spring:message message="${entry.value}" />
</div>
</c:forEach>
Надеюсь, это поможет вам.
Ответ 3
После того, как я несколько раз ударил головой, я, наконец, сделал это.
Я использую spring 3.1 и имеет поддержку requestFlashAttributes, которые передаются через перенаправления.
Ключом к решению моей проблемы было изменение типов возвращаемых данных на строки, а не объекты ModelAndView.
Этот парень сделал отличную запись об использовании флеш-сообщений с помощью spring (http://www.tikalk.com/java/redirectattributes-new-feature- spring -mvc-31)
Ответ 4
Вы должны держать его простым и использовать определенные коды HTTP 1.1. Таким образом, для успешного вызова вы должны вернуть 200 OK. И на стороне клиента, если вы хотите показать конкретное сообщение пользователю, когда контроллер вернет 200, вы покажете его там.
Ответ 5
Если вы имеете в виду, что страница перезагружается после некоторого POST, вы можете включить в свой флаг флаг (JSP или скорость или все, что вы используете). Например. что-то вроде этого
<c:if test="${not empty resultMessage}">
<spring:message code="${resultMessage}" />
</c:if>
И ваш комплект сообщений должен содержать сообщение для этого кода.
Если вы отправляете AJAX POST для отправки некоторых данных (т.е. страница не перезагружается, и вам нужно показать сообщение), вы могли бы
1) сделайте динамические JS файлы (JSP или Velocity, еще раз) и добавьте теги <spring:message>
(мне не нравится эта опция)
или
2) следуйте советам этой ссылке и используйте @ResponseBody
, чтобы вернуть объект статуса в ваш JS. Внутри объекта, который вы отмечаете как @ResponseBody
, вы можете указать как статус, так и сообщения. Например. используя ваши пакеты сообщений, как в в этом случае.
Ответ 6
Простейшим средством отображения сообщений на вашем JSP является обладание объектом (возможно, сеансом, возможно, запросом), который содержит сообщения, которые вы хотите отобразить. Например, вы можете сделать следующее:
... java stuff ...
List messages = new ArrayList();
messages.add("some message");
messages.add("some other message");
request.addAttribute("NotableMessages", messages);
... java stuff ...
... jsp and JSTL stuff ...
<c:if test="not empty NotableMessages">
<ul>
<c:forEach items="${NotableMessages}" var="item">
<li>${item}</li>
</c:forEach>
</ul>
</c:if>
... jsp stuff ...
Ответ 7
Наряду с соответствующим кодом состояния вы всегда можете установить заголовок с нужным вам сообщением. Конечно, это действительно хорошая идея, если у вас есть контроль над тем, как будет использоваться контроллер (т.е. Нет третьих сторон).