Удаление сообщений JSF из флэш-памяти - PullRequest
9 голосов
/ 27 июля 2010

У меня есть одна страница, которая что-то делает, и когда пользователь нажимает кнопку, пользователь перенаправляется на другую страницу и отображается сообщение. Вот мой код:

 public String confirm() {
    FacesContext context = FacesContext.getCurrentInstance();
    Flash flash = context.getExternalContext().getFlash();
    flash.setKeepMessages(true);
    FacesMessage msg = new FacesMessage("Succesful", "Release is confirmed!");
    context.addMessage(null, msg);
    return "/prot/expert/releases?faces-redirect=true";
 }

Я использую компонент p: growl, который отображает мое сообщение на странице «релизы». Пока все хорошо.

Но затем на любой последующей странице, которая имеет p: growl (или если я перейду на другую страницу и вернусь), сообщение будет отображаться снова и снова, и я не могу его убить.

Я пробовал что-то вроде:

<c:set target="#{flash}" property="keepMessages" value="false" />

на странице, содержащей p: рычание, я попытался очистить вспышку от бобов и т. Д.

Сообщение сохраняется и отображается снова. Если я удалю flash.setKeepMessages (true); из кода выше ничего не отображается.

Что я делаю не так?

Ответы [ 3 ]

7 голосов
/ 19 июня 2011

Я получил точно такую ​​же проблему на JBoss AS 6 с Mojarra 2.0.3 и Mojarra 2.1.1.Вспышка должна выдержать только одно перенаправление, но на практике это не всегда так.

В методе действия у меня в основном один и тот же код:

// [add global faces message]
FacesContext.getCurrentInstance().getExternalContext().getFlash().setKeepMessages(true);
return "/someView.xhtml?faces-redirect=true";

Я вижу три симптомапроблема:

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

Проблема 2 может быть объяснена путем понимания того, что область действия флэш-памяти основана на использовании файлов cookie(по крайней мере, в Мохарре).Относительно мало людей, кажется, понимают врожденную проблему с этим.Я нашел этот связанный вопрос, но у него нет ответов: Свободна ли область видимости Flash от условий гонки?

Кроме того, при попытке воспроизвести проблему я получил примерно 2 /3 шанса реально воспроизвести его.Иногда он действительно выживает только после одного перенаправления, иногда он исчезает после нескольких обновлений (основанных на времени или около того?), А иногда он просто застревает, и единственный способ избавиться от него - перезапустить мой сервер (!).

Может, я где-то что-то не так делаю?

Наблюдая за установкой файлов cookie, я заметил следующее:

После первоначального запуска действия, которое выполняет перенаправление:

POST Response
Set-Cookie csfcfc=_50Xfr

GET Response
Set-Cookie csfcfc=50Xfn_51Xfn

Здесь следует отметить, что ответ на запрос GET для перенаправления снова устанавливает cookie.Вы хотите подумать, что для флеш-области куки-файл должен быть удален здесь.

Если я отправлю форму на представление, которое перенаправит меня, произойдет следующее:

POST Response
Set-Cookie csfcfc=_50Xfn

Сообщение исчезло.

Однако, когда я снова отправляю форму, происходит следующее:

POST Response
Set-Cookie  csfcfc=_52Xfn

И сообщение возвращается: (

ЕслиЯ снова отправляю форму:

POST Response

Больше нет заголовка Set-Cookie, и сообщение снова исчезает. Если я продолжу отправлять форму, последний cookie (csfcfc = _52Xfn) будет отправляться насервер, но больше не устанавливаются новые файлы cookie и сообщения не отображаются.

Редактировать:

Во время отладки я обнаружил критическую секцию в ELFlash.java (Mojarra 2.0.3):

void saveAllMessages(FacesContext context) {
    // take no action on the GET that comes after a REDIRECT
    Map<Object, Object> contextMap = context.getAttributes();
    PreviousNextFlashInfoManager flashManager;
    if (null == (flashManager = getCurrentFlashManager(contextMap, true))) {
        return;
    }
    if (flashManager.getPreviousRequestFlashInfo().isIsRedirect()) {
        return;
    }
}

В контексте запроса GET после перенаправления можно было бы предположить, что isIsRedirect вернет true, но вернул false. Это может быть локальной проблемой, которую я собираюсь исследовать далее.

ПроцентыСледует отметить, что значения cookie на самом деле имеют некоторое значение, согласно следующему:

 FirstTimeThru("f"),
 SecondTimeThru("s"),
 IsRedirect("r"),
 IsNormal("n");

Итак, первый cookie (_50Xfr) - это FirstTimeThru и IsRedirect.

4 голосов
/ 20 ноября 2013

Ваша конкретная проблема вызвана ошибкой в ​​старых версиях Mojarra, в частности , проблема 1751 .Тем не менее, было много сообщений о проблемах для области флеш-памяти впоследствии.Область действия флэш-памяти используется в более старых версиях Mojarra, известных по следующим основным проблемам:

В целом можно сделать вывод, что вам нужно обновить Mojarra до минимума 2.1.27 / 2..2.5 (срок исполнения 2 января 2014 г.), чтобы избавиться от всех этих проблем.

0 голосов
/ 20 ноября 2013

Попробуйте установить свойство redisplay в false:

<p:growl redisplay="false"/>
...