Learning JSF2: Using Flash scope

JSF 2 provides two new scopes on top of the standard Servlet scopes (request, session, application). One of them is the view scope. View scope was covered in Managed beans article. The other scope is Flash which I’m going to cover here. Let’s start with a very simple example.

Managed bean:

@ManagedBean(name = "bean")
public class Bean {
   private String text;
   // getter and setter

   public String nextpage (){
       return "page2";
   }
}

As scope is not specified, the default scope is request.

JSF page (page1.xhtml):


   
	
	
	
   


JSF page (page2.xhtml):

#{bean.text}

This application is very simple. The first page will render this (shown after entering text):

Once button is clicked, we navigate to the next page and text value is displayed:

One thing to note. We didn’t define a navigation rule in JSF configuratin file. We used JSF 2 implicit navigation feature:

public String nextpage (){
       return "page2";
 }

JSF will try to locate page called page2.xhtml and navigate to it. Navigation was was covered in this article.

Another thing to keep in mind that by default JSF does server forward when it invokes navigation. You probably noticed this this causes the URL in browser address bar always be one behind the actual page. This happens because we do a postbback (submit the page to itself) but return a different page to the browser.

One way to solve this problem is to use a redirect. A redirect can be defined in JSF configuration file or also added to our implicit navigation:

public String nextpage (){
       return "page2?faces-redirect=true";
 }

Running the application with above change and navigating to the second page will produce an empty page. When using a redirect, a page is submitted and once we reach the navigation step, the server sends the browser back a response telling it to send a new request to a specified URL. Now, this URL now matches the actual page we would be displaying. While we solved the URL/page matching problem, we now created another problem. As the browser sends a new request, any request-scoped objects will be recreated (or the old one gone). As our bean was in request scope, a new one was created and we lost the original text. That’s where the new Flash scope can help us.

Objects placed inside the Flash scope will be available for the subsequent request and then cleared. In other words, objects placed in Flash scope will survive a redirect. The Flash scope is very similar to temporary Seam conversation.

To place an object into Flash scope we use this:

public String nextpage (){
   JSFUtils.flashScope().put("bean", this);
   return "page2?faces-redirect=true";
 }
public class JSFUtils {
   public static Flash flashScope (){
	return (FacesContext.getCurrentInstance().getExternalContext().getFlash());
   }
}

Then, to read the values from Flash scope on the result page, we update the page like this:

#{flash.bean.text}

this will also work:

#{flash['bean'].text}

View scope wouldn’t work here as it works when we are staying on the same view (page). In our case, we navigated to a different view (page).

20 thoughts on “Learning JSF2: Using Flash scope

  1. I can’t find the ELFlash class from JSF2.0 JavaDoc, do you mean “javax.faces.context.ExternalContext.getFlash()” ?

    BTW, like your blog

  2. Thanks a lot, and this lead to some more questions:

    1> what’s the difference between com.sun.faces.context.flash.ELFlash and javax.faces.context.ExternalContext other than the packaging/naming?

    2> do I have to use the ELFlash or better use ExternalContext? (I’m kind nervous about com.sun.* stuff)

  3. Hey Max! Nice article :) Have you tried the Seam 3 Faces Flash scope by any chance? We decided not to use the JSF flash because of a few problems:

    Namely, the flash from the current request is not the same as the one used during the lifecycle(non render phases) of the next request. While it’s not a “bug,” it presents problematic behavior should the next requested view have f:viewParams, which cause the lifecycle to be invoked, this time with a brand new flash scope… eg: the information from the previous request is not available, and causes a lot of confusion and bugs.

    We just keep the same flash alive until the page is rendered, and it’s a much simpler approach / usage.

    Thoughts?
    –Lincoln

  4. @Lincoln: no, I haven’t tried Seam 3 Faces Flash scope. Will have to try it. But what you describe is an interesting problem, I wonder if the EG should address this issue.

  5. Hi,

    I am using flash scope to pass parameters from one view to another using view scoped beans. So far i have only got 1 problem:

    – When the user refreshs the page (f5 button or browser reload) the view scope bean associated with the current is reconstructed (as if another view was asked) therefore losing the parameter passed.

    Why is this happening? How can I bypass this problem without using session scoped beans and/or get parameters?

    Ty.

  6. Max,

    I have a search of items and when I change the page wich scope flash (following your tuto) the result is displayed. But I have a ajax request, and after this ajax request the result of search go away!

    How can I persist the values of my bean?

  7. @Danilo: I’m not sure what the problem is, but Flash scope should work with Ajax request as well. It only works if you stay on the same page (view).

  8. Pingback: Java Server Faces Managed Beans and Scope « Signpost6

  9. Pingback: How To Save Struts Messages After a Redirect : philihp.com

  10. Pingback: printing bean data in another page (RequestScope) | BlogoSfera

  11. Pingback: printing bean data in another page (RequestScope)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s