Удаление сообщений JSF из флэш-памяти

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

 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";
 }

Я использую компонент ap: growl, который отображает мое сообщение на странице "релизы". Все идет нормально.

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

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

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

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

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

Что я делаю неправильно?

3 ответа

Я получил точно такую ​​же проблему на 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. Вы хотите думать, что для флеш-области 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");

Таким образом, первое печенье (_50Xfr), является FirstTimeThru и IsRedirect,

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

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

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

<p:growl redisplay="false"/>
Другие вопросы по тегам