Подтвердить что ты не робот

Сообщения о состоянии на сайте Spring MVC (контроллер аннотации)

Каков наилучший способ организации сообщений о статусе ( "Ваши данные были успешно сохранены/добавлены/удалены" ) на сайте Spring MVC с использованием контроллера аннотаций?

Итак, проблема заключается в отправке сообщения из POST-метода в contoller.

4b9b3361

Ответ 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

Наряду с соответствующим кодом состояния вы всегда можете установить заголовок с нужным вам сообщением. Конечно, это действительно хорошая идея, если у вас есть контроль над тем, как будет использоваться контроллер (т.е. Нет третьих сторон).