SeamFramework.orgCommunity Documentation

Chapter 42. Faces Scoping Support

42.1. @RenderScoped
42.2. @Inject javax.faces.context.Flash flash
42.3. @ViewScoped

JSF 2.0 introduced the concept of the Flash object and the @ViewScope; however, JSF 2.0 did not provide annotations accessing the Flash, and CDI does not support the non-standard ViewScope by default. The Seam Faces module does both, in addition to adding a new @RenderScoped context. Beans stored in the Render Scope will survive until the next page is rendered. For the most part, beans stored in the ViewScope will survive as long as a user remains on the same page, and data in the JSF 2 Flash will survive as long as the flash survives).

Beans placed in the @RenderScoped context are effectively scoped to, and live through but not after, "the next Render Response phase".

You should think about using the Render scope if you want to store information that will be relevant to the user even after an action sends them to another view. For instance, when a user submits a form, you may want to invoke JSF navigation and redirect the user to another page in the site; if you needed to store a message to be displayed when the next page is rendered -but no longer- you would store that message in the RenderContext. Fortunately, Seam provides RenderScoped messages by default, via the Seam Messages API.

To place a bean in the Render scope, use the @org.jboss.seam.faces.context.RenderScoped annotation. This means that your bean will be stored in the org.jboss.seam.context.RenderContext object until the next page is rendered, at which point the RenderScope will be cleared.

@RenderScoped

public class Bean {
    // ...
}

@RenderScoped beans are destroyed when the next JSF RENDER_RESPONSE phase ends, however, if a user has multiple browser windows open for the same user-session, multiple RenderContexts will be created, one for each incoming request. Seam Faces keeps track of which RenderContext belongs to each request, and will restore/destroy them appropriately. If there is more than one active RenderContext at the time when you issue a redirect, you will see a URL parameter ?fid=... appended to the end of the outbound URL, this is to ensure the correct context is restored when the request is received by the server, and will not be present if only one context is active.

Caution

If you want to use the Render Scope with custom navigation in your application, be sure to call ExternalContext.encodeRedirectURL(String url, Map<String, List<String>> queryParams) on any URL before using it to issue a redirect. This will ensure that the RenderContext ID is properly appended to the URL, enabling the RenderContext to be restored on the subsequent request. This is only necessary if issuing a Servlet Redirect; for the cases where Faces non-redirecting navigation is used, no URL parameter is necessary, and the context will be destroyed at the end of the current request.

JSF 2 does not provide proper system events to create a functional @FlashScoped context annotation integrated with CDI, so until a workaround can be found, or JSF 2 is enhanced, you can access the Flash via the @Inject annotation. For more information on the JSF Flash, read this API doc.



public class Bean {
   @Inject private Flash flash;
   // ...
}

To scope a bean to the View, use the @javax.faces.bean.ViewScoped annotation. This means that your bean will be stored in the javax.faces.component.UIViewRoot object associated with the view in which it was accessed. Each JSF view (faces-page) will store its own instance of the bean, just like each HttpServletRequest has its own instance of a @RequestScoped bean.

@ViewScoped

public class Bean {
    // ...
}