tags:

views:

966

answers:

3

I have a JSF application that makes much use of session-scoped variables. A new requirement is that the user should be able to open N numbers of the application. However, since much of the state is session-scoped, when the client opens a 2nd instance of the app, view data from the first app bleeds into the newly opened app.

At this point, changing all the session-scoped beans to request-scoped beans would be very difficult. Is there a way to solve this problem at a higher level, by perhaps mapping external (client) sessions with one or more internal (artificially created and used by JSF) session objects?

A: 

You can control how the session is provided to the JSF application via the FacesContextFactory (which provides the FacesContext which contains the ExternalContext). This needs to be configured in a faces-config.xml so JSF can pick it up during initialization. If you use a constructor of the form MyFacesConfigFactory(FacesConfigFactory) JSF will pass the previously configured factory, allowing you to decorate the underlying implementation.

Some issues you may encounter:

  • You would need control over what it means to "open the application" in order to create a sub-session. For example, a form that creates the sub-session.
  • You need some mechanism to match requests with your session - probably through the ExternalContext URL encoding methods (which will need to be used religiously; well behaved components already use these).
  • You need a whole layer of session management code - I'm thinking about folks creating huge HTTP sessions just by opening multiple "instances" of the app.
  • There are probably plenty of edge conditions and other things I didn't think of.

This is an interesting approach to the problem, but I wouldn't expect it to be a quick fix.

McDowell
+1  A: 

There are a few frameworks that fix this problem for you but I'm not sure if adopting a new framework is an acceptable solution.

Seam offers the concept of conversation based scope, which would probably do what you need it to do. I also know that Spring has an equivalent scope.

Drew
If I recall correctly, Apache Orchestra is another option for adding conversation scope to JSF.
McDowell
Tomahawk (with saveState component) or RichFaces (keepAlive component) can also provide such functionality...
romaintaz
+1  A: 

Do you really need to work with session objects directly? Why not have a session-scoped Map, mapping unique "sub-session" IDs to Maps for the attributes of the sub-session? The down side is you'll need to include your sub-session ID on every page as a hidden parameter that is included in every client request, and all of your EL for session attributes will need to be something like "#{subSession.mySubSessionId.myAttribute}". You may run into other issues, as a redirect or browser refresh may destroy your sub-session ID.

Overall, I'd look for a framework solution. There's a better chance a framework solution has less bugs, and it also means there's less code for you to create and maintain. It's much easier to focus on actual app development when details of this nature are taken care of for you.