Oracle Blog

Adrift in the blogging sea...

JSF 2.0 New Feature Preview Series (Part 5) EDR1 Potpourri

This seventh entry in the JSF 2.0 New Feature Preview Series wraps up the content included in EDR1 (yes, I know I'm a bit behind). The last entry covered resource re-location. This entry will include information on the miscellaneous bits that were added as a side effect of adding the larger feature sets.

View Scope

This new scope allows attributes to be associated with a particular view. Attributes within the view scope persist until the user navigates to a new view at which they will be cleared out.

The view scope, like request or session, can be accessed via the EL using the identifier viewScope (e.g. #{viewScope.attrName}). The view scope can also be accessed from code by calling UIViewRoot.getViewMap().

To have parity with the Servlet specification, there are two events associated with the lifecycle of the view scope: ViewMapCreatedEvent and ViewMapDestroyedEvent. ViewMapCreatedEvent is fairly straight forward. ViewMapDestroyedEvent is a bit different in that it will be fired when the view map is cleared (i.e. Map.clear() is invoked).

I'm sure most of us have been bit by the case where one is trying to use a request scoped attribute for the rendered or readonly attribute only to find it doesn't really affect the rendering of the component (due to the lifecycle of the request attribute). You're then forced to use session scope or perform some other actions within code to get around it. Using the view scope, you're able to achieve the same result as a session scoped value, but without it remaining in the session and as said previously, the values are cleared as soon as the user navigates to a new view.

Component Implicit EL Object

The component implicit EL object allows developers to access the component associated with the current tag via the EL. So#{component.attributes.bar} would access the component's attributes map and return the value associated with the key, bar. Developers can also access the component that is currently being processed (i.e. during decodes, validation, or rendering) from code by callingUIComponent.getCurrentComponent().

FacesContext Attributes Map

Because we are always trying to improve performance (even in the smallest ways), this addition is close to my heart. To support resource injection for managed beans that are request scoped, we use (I believe MyFaces does as well) a ServletRequestListener and a ServletRequestAttributeListener so we can be notified when a ServletRequest goes out of scope and when attribute values are changed or removed. When these events are triggered we can take the appropriate action on the request scoped managed bean. However, each time one of these events is triggered, a new Event object is created by the container.

Mojarra, and I'm sure most component libraries, use the request scope for private per-request state, however doing so triggers the aforementioned events. This might not be so bad, but consider when a component library or an application adds request listeners of their own. Two or more events are being created per action.

Because of the potential for Event creation to be a burden on the server, we added the FacesContext attributes map (FacesContext.getAttributes()). This API is really there for JSF implementors or component set authors to use so that they can avoid the request scope and firing events for private state. If utilized this leaves the request scope for the developer's application and keeps the private runtime/components state out of the mix.

It was deadly required. Currently their was no elegant way of clearing session data. This current addition to jsf spec will be blessing for app server memory and application performance.

Question - As most of the data may not be required after specific business process or set of GUIs, can this scope be used for this purpose ?
That is in simple terms a bean may not be required if user navigates to some other GUI module in the web-application or jumps to some other business process ? If not then we should have one scope for that too.

@Rahul: I don't believe the JSF 2.0 spec will add a process scope (I believe that is what it is called in Seam) in favor of letting the WebBeans specification provide that. The view scope could be used for this in a limited manner if the need for particular data was on a per-view bases. If the data spans multiple views, then you're back to managing the session scope.

What if there are 2 independent requests from the same session made to different views? For example when application is using frames or when user opens new window?

After reading the description above I see the view scope variables will be removed if any other view is rendered. So in case of such 2 requests made to the different views, wouldn't each request destroy the view scoped attributes of another view?