A conversation scope fits between a Session scope and a Request scope in J2EE terms. An object in a session is specific to a particular user of a web app. If you place an object in the users session it will be available on every page hit the user makes.
A conversation scope defines a long lived set of data that is specific to a process, such as configuring a product, or filling out a customers personal and credit information. It differs from a session scope in that one user should be able to have multiple of th same type of conversation at the same time. You might actually have to help more than one customer at a time, or configure multiple products, one on each tab in your web browser.
Not directly. I have written an Interceptor that implements a Conversation Scope for possible inclusion in Struts 2 in the future. We'll see what happens. In the mean time I've created an example, including the supporting classes.
This extension to Struts 2 consists of two classes, an Interceptor and an Interface for your Actions to implement. That's it.
The Interceptor does most of the heavy lifting. It creates new conversation id's. Marshals the data from the users conversation scope into your Action, and cleans up when you mark the conversation complete.
The interface consists of only a few methods:
package org.apache.struts2.interceptor;
public interface ConversationScopeAware {
public static final String S2_CONVERSATION_SCOPE = "S2_CONVERSATION_SCOPE";
public static final String S2_CONVERSATION_ID = "S2_CONVERSATION_ID";
public static final String S2_VALUE_STACK_MODEL_KEY = "s2cmodel";
public static final String S2_VALUE_STACK_MODEL_ID_KEY = "modelid";
/** Get the id of the current conversation the action is handling. */
public String getConversationId ();
/** Set the id of the current conversation the action is handling. */
public void setConversationId (String in);
/** Get the conversation model. */
public Object getConversationModel ();
/** Set the conversation model. */
public void setConversationModel (Object in);
/**
* Prepare the conversationModel. So it can be saved in the conversationScope and
* pushed onto the top of the value stack. The action needs to maintain a reference
* to the prepared model.
*/
public Object prepareConversationModel ();
/**
* Find out if the conversation is finished. If true the conversation model can
* be removed from the conversationScope.
*/
public boolean isConversationFinished ();
}
The most important concept to grasp is the conversationModel. This is very similar to the ModelDriven actions. Basically you have some Object that represents the data you want to collect and process as you have a conversation with your user. Your model object can be almost anything, including your rich domain objects. I would discourage you from using a Map though.
When Struts 2 receives a request for a ConversationScopeAware action it will check to see if there is a stored conversation using the conversation id. If there is no conversation it will ask the Action to prepare the conversation model by calling ConversationScopeAware#prepareConversationModel(). This is your chance to setup your data model that you will fill in over your conversation. Once you have prepared your model the interceptor will push it onto the top of the stack, so the properties can be filled in with the user's parameters.
In your view you will need to include the conversation id in a hidden field of your form:
<s:hidden name="S2_CONVERSATION_ID" value="%{conversationId}" />
Once you have finished with the conversation you can mark it for removal from the users conversation scope. After running the action the interceptor will call isConversationFinished(). If this returns true it will dispose of the saved conversation model.
Attached to this post is a Maven project, which demonstrates the use of a conversation. Download it and build it using: mvn package. This will create a war file under the target directory. Deploy that to your favorite servlet container and point your browser at it (ex: http://localhost:8080/tutorial/).
You will be prompted to enter your name, and click the next button. Also at the bottom there is a link to start another conversation. You can have as many conversations going as you like. The data for each of them is independent.
Take a look at src/main/java/tutorial/ConversationAction.java to see how it all works. In short you have a simple Action, which includes an inner class to store its data called ConversationModel. It instantiates a copy of ConversationModel when prepareConversationModel() is called. The Interceptor stores it transparently for the Action. On subsequent hits the model will already be injected into the action by the Interceptor allowing the Action to act on any data that has been previously entered by the user.
The example takes the user through a few steps using logic in the execute() method, eventually sending the result page which displays all of the collected data.
This example doesn't show use of the prepare() method, nor the validate() method in conjunction with our conversation scope. You can use the prepare() to add data to your conversation model as the user fills out forms, and you can use th validate() to validate each screen the user submits.
| Attachment | Size |
|---|---|
| tutorial.tar_.gz | 15.45 KB |
Recent comments
1 week 6 days ago
2 weeks 3 days ago
3 weeks 11 hours ago
3 weeks 6 days ago
4 weeks 2 days ago
4 weeks 2 days ago
5 weeks 1 hour ago
8 weeks 1 day ago
8 weeks 6 days ago
8 weeks 6 days ago