Seam 2.0.0.BETA1
I would like a shopping website that allows users to have multiple carts open in different
browser windows at the same time. Seam's conversation model appears to provide a
solution: use a long running conversation for each cart and nested conversations
everywhere a regular application would use a conversation.
One of the problems is how to transparently connect a user back to their cart (most
recently accessed session) if they leave the site and come back using a url without the
conversation id? I've tried the following solution:
| pages.xml (fragment):
|
| <page view-id="*" action="#{conversationManager.manage}">
|
| ConversationManager.java:
|
| @Name("conversationManager")
| @Scope(ScopeType.SESSION)
| public class ConversationManager
| {
| private Stack<String> conversationStack = new Stack<String>();
|
| public String manage()
| {
| Manager manager = Manager.instance();
| HttpServletRequest httpServletRequest = (HttpServletRequest)
FacesContext.getCurrentInstance().getExternalContext().getRequest();
| String conversationIdRequestParameter =
httpServletRequest.getParameter(manager.getConversationIdParameter());
|
| if(! manager.isLongRunningOrNestedConversation())
| {
| ConversationEntries conversationEntries = ConversationEntries.instance();
|
| if(conversationEntries.getConversationEntries().size() == 0)
| {
| manager.beginConversation();
| conversationStack.push(Conversation.instance().getId());
| }
| else if
| (
| conversationEntries.getConversationEntries().size() > 0
| && conversationIdRequestParameter == null
| )
| {
| while(conversationStack.size() > 0)
| {
| String conversationId = conversationStack.pop();
| ConversationEntry conversationEntry =
conversationEntries.getConversationEntry(conversationId);
| if(conversationEntry != null)
| {
| conversationEntry.redirect();
| }
| }
| }
| }
| else if(manager.isLongRunningConversation())
| {
| try
| {
| if(conversationStack.peek() != Conversation.instance().getId())
| {
| conversationStack.remove(Conversation.instance().getId());
| conversationStack.push(Conversation.instance().getId());
| }
| }
| catch(EmptyStackException e){}
| }
|
| return null;
| }
| }
For every view the manage method:
- begins a long running conversation for new sessions.
- for requests that have conversations but no conversation id, redirects to last accessed
existing conversation.
I've not tested this extensively but it appears to work as intended.
Because the conversation holds the cart, its timeout should be set to a long span. However
when creating nested conversations it would be preferable for them to have a short span.
Here's where I've run into a problem. I can set the conversation timeout like so:
Conversation.instance().setTimeout(int);
but as soon as I go to the next page the timeout will be back to the default setting.
I've would like to use an approach like:
ConversationEntries.instance().getConversationEntry("2").setTimeout(int);
which would set the ConversationEntry dirty, but this method is not visible.
Here are my questions:
=============================================
- How do you permanently change a conversation's timeout?
- Is there a better multiple cart solution without hijacking the seam conversation model?
(e.g. storing the carts in the sesssion and creating management similar to conversations)
- If this is an acceptable solution would it be better implemented as a servlet filter
instead of mapping an action to the "*" view in pages.xml?
=============================================
Thanks in advance for your feedback.
references:
http://www.jboss.com/index.html?module=bb&op=viewtopic&t=109084
View the original post :
http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4082227#...
Reply to the post :
http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&a...