Removing JSF messages from the flash
Asked Answered
L

3

9

I have one page that does something and when the user clicks a button, the user is redirected to another page and a message is displayed. Here is my code:

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

I use a p:growl component which displays my message on the "releases" page. So far so good.

But then on any subsequent page that has p:growl (or if I go to another page and go back) the message is displayed again and again and I can't kill it.

I tried something like:

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

on the page that has the p:growl, I tried clearing the flash from the backing bean etc.

The message is retained and displayed all over again. If I remove flash.setKeepMessages(true); from the code above then nothing is displayed.

What am I doing wrong?

License answered 27/7, 2010 at 11:34 Comment(5)
That's weird, I'm doing almost exactly the same thing, but displaying the message using a h:messages tag instead of a p:growl tag. The message goeas away as expected for me. May try using h:messages instead, just to see if it works?Meantime
Hm, now it is working. Except for when the user presses the Back button, then the message is displayed, but I guess that's normal behaviour. Do you try setting flash.setKeepMessages() to false on the second page?License
There's an JIRA issue open for this: java.net/jira/browse/JAVASERVERFACES-1751 can't believe this is still open, as it completely breaks the flash scope functionality.Bruns
This (very old) posting reports a similar problem as yours and the exact same problem as I describe below: java.net/projects/glassfish/lists/webtier/archive/2009-10/… Ed Burns replied he would react, but it seems he never did.Crackup
Yet another one: #5868584Crackup
C
7

I did get the exact same problem on JBoss AS 6 with both Mojarra 2.0.3 and Mojarra 2.1.1. The flash should survive only one redirect, but in practice it not always does.

In an action method I have basically the same code:

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

I've been seeing three symptoms of the problem:

  1. After doing a postback on someView, the flash faces message keeps being displayed
  2. After a clean request to a completely different page, the face message is also displayed
  3. After going again through the code that adds the faces message, you'll get two of the same messages on someView

Issue 2 can be explained by realizing that the flash scope is cookie based (at least in Mojarra). Relatively few people seem to understand the inherent problem with that. I've found this related question, but it has no answers: Is Flash scope free of race conditions?

Also, when trying to reproduce the problem I've got approximately a 2/3 chance of actually reproducing it. Sometimes it indeed only survives a single redirect, sometimes it's gone after a few refreshes (time based or so?) and sometimes it just sticks around and the only way to get rid of it is restarting my server(!).

Maybe I'm doing something wrong somewhere?

Observing the cookies being set, I noticed the followed:

After initially triggering the action that does the redirect:

POST Response
Set-Cookie csfcfc=_50Xfr

GET Response
Set-Cookie csfcfc=50Xfn_51Xfn

The thing to notice here is that the response from the GET request for the redirect again sets a cookie. You want think that for a flash scope the cookie would need to be deleted here.

If I submit a form on the view towards I'm redirected, the following happens:

POST Response
Set-Cookie csfcfc=_50Xfn

The message is now gone.

However, when I submit the form once more, the following happens:

POST Response
Set-Cookie  csfcfc=_52Xfn

And, the message is back :(

If I again submit the form:

POST Response

There is no more Set-Cookie header and the message in once again gone. If I continue submitting the form, the last cookie (csfcfc=_52Xfn) keeps being send to the server, but there are no more new cookies being set and no messages are displayed.

Edit:

During debugging I came across a critical section in 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;
    }
}

During the context of the GET request following the redirect, one would suppose isIsRedirect would return true, but it returned false. This could be a local problem, that I'm going to investigate further.

Interesting to note is perhaps that the cookie values actually have some meaning, according to the following:

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

So the first cookie (_50Xfr), is a FirstTimeThru and a IsRedirect.

Crackup answered 19/6, 2011 at 17:43 Comment(1)
The comment in ELFlash says: Any entries put into the "next" flash map on request N will be expired at the end of request N+1., but this never seems to happen. I would also expect JSF to write out an empty cookie at this request N+1 in order to delete it from the client, but this too never happens.Bruns
B
4

Your concrete problem is caused by a bug in older Mojarra versions, specifically issue 1751. There have however been many issue reports for the flash scope afterwards. The flash scope is in older Mojarra versions known for the following major problems:

All in all, concluded can be that you'd need to upgrade to a minimum of Mojarra 2.1.27 / 2.2.5 (due date 2 january 2014) in order to get rid of all those problems.

Bergman answered 20/11, 2013 at 10:20 Comment(0)
C
-2

Try setting property redisplay to false:

<p:growl redisplay="false"/>
Clockwise answered 20/11, 2013 at 7:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.