Conversation scope
The conversation scope holds state associated with a user of the system, and spans multiple requests to the server.A conversation represents a task—a unit of work from the point of view of the user.
The conversation context is active during any JSF request. Most conversations are destroyed at the end of the request. If a conversation should hold state across multiple requests, it must be explicitly promoted to a long-running conversation.
Conversation demarcation
CDI provides a built-in bean for controlling the lifecycle of conversations in a JSF application. This bean may be obtained by injection:
@Inject Conversation conversation;
To promote the conversation associated with the current request to a long-running conversation, call the begin() method from application code. To schedule the current long-running conversation context for destruction at the end of the current request, call end().
public void beginConversation() { if (conversation.isTransient()) { conversation.begin(); conversation.setTimeout(1000 * 60 * 30); } } public void endConversation() { conversation.end(); }
The container is permitted to destroy a conversation and all state held in its context at any time in order to conserve resources. The Conversation object provides a method to set the timeout. The timeout is the period of inactivity before the conversation is destroyed (as opposed to the amount of time the conversation is active).
The method beginConversation() may be called when the page is generated by the means of the JSF preRenderView event.
... <f:event type="preRenderView" listener="#{action.beginConversation}"/> <h:head> ... </h:head> ...
Conversation propagation
The conversation context automatically propagates with any JSF faces request (JSF form submission) or redirect. It does not automatically propagate with non-faces requests, for example, navigation via a link.
We can force the conversation to propagate with a non-faces request by including the unique identifier of the conversation as a request parameter. The CDI specification reserves the request parameter named cid for this use. The unique identifier of the conversation may be obtained from the Conversation object, which has the EL bean name javax.enterprise.context.conversation.
Therefore, the following link propagates the conversation:
<a href="/addProduct.jsp?cid=#{javax.enterprise.context.conversation.id}">Add Product</a>
It's probably better to use one of the link components in JSF 2:
<h:link outcome="/addProduct.xhtml" value="Add Product"> <f:param name="cid" value="#{javax.enterprise.context.conversation.id}"/> </h:link>
In order to keep the code simple, you can define custom tags beginConversation and conversationId:
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core"> <f:event type="preRenderView" listener="#{action.beginConversation}"/> </ui:composition>
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core"> <f:param name="cid" value="#{javax.enterprise.context.conversation.id}"/> </ui:composition>