Сообщения о состоянии на сайте Spring MVC (контроллер аннотаций) - PullRequest
26 голосов
/ 24 апреля 2010

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

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

Ответы [ 7 ]

16 голосов
/ 06 апреля 2012

Как упомянул muanis, начиная с весны 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> 
8 голосов
/ 06 декабря 2010

Проверенным подходом является использование специальной области флеш-памяти для сообщений, которые должны храниться до следующего запроса GET.

Мне нравится использовать флэш-объект в области сеанса:

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>

Надеюсь, это поможет вам.

1 голос
/ 10 февраля 2012

После некоторого стука в голову, я наконец заставил это работать.

Я использую Spring 3.1, и он поддерживает атрибуты requestFlashAttributes, которые передаются через перенаправления.

Ключом к решению моей проблемы было изменение возвращаемых типов на строки, а не объекты ModelAndView.

Этот парень сделал отличный пост об использовании флеш-сообщений с пружиной (http://www.tikalk.com/java/redirectattributes-new-feature-spring-mvc-31)

0 голосов
/ 18 ноября 2010

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

0 голосов
/ 18 ноября 2010

Самым простым способом отображения сообщений в вашем 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 ...
0 голосов
/ 30 июня 2010

Если вы имеете в виду, что страница перезагружается после некоторого 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, вы можете поместить как статус, так и сообщения. Например. используя ваши сообщения, как в в этом случае .

0 голосов
/ 27 апреля 2010

Вы должны быть простыми и использовать специальные коды состояния HTTP 1.1.Таким образом, для успешного вызова вы должны вернуть 200 ОК.И на стороне клиента, если вы хотите показать конкретное сообщение пользователю, когда контроллер возвращает 200, тогда вы показываете его там.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...