PDA

View Full Version : Difference between flowScope and conversationScope?


Goonie
Apr 9th, 2006, 08:32 AM
Hello everyone,

what's the difference between ${flowScope...} and ${conversationScope...}? I am missing a discussion about scopes in the documentation, as well as a description of the ${} binding expressions (are they compatible to JSTL expressions?).

For one decision state and some action states, I need to the get name of the logged in user? Is there such thing as a requestScope? How do I get such things, without binding too much to Servlet specific things?

Regards,

Andreas

Keith Donald
Apr 9th, 2006, 11:18 AM
This is briefly discussed in the FlowExecution section of the reference docs but should be clarified further.

Conversation scope is shared by all flow sessions, scoped with the FlowExecution itself. When combined with a continuation-based repository, conversation scope is also shared by all FlowExecution continuations. This means if you go back and continue from a previous view-state data in converation scope will still be available.

Flow scope is effectively "flow session scope", local to a specific flow session. When the flow session ends it is popped off the stack and all data in flow scope goes away. In addition, when combined with a continuation-based repository the flow session stack is serialized as part of each continuation. So this means when you go back and continue from a previous view-state data in flow scope will reflect the state of the flow *at that point* (data collected at later steps will be undone).

Hope this helps,

Keith

Goonie
Apr 9th, 2006, 11:49 AM
Thanks for your help, Keith. Flow scope and conversation scope are now pretty clear to me. Guess that request scope has gone away since you wrote the ServerSide article in May 2005? (http://www.theserverside.com/articles/article.tss?l=SpringWebFlow)

In the meantime, I have found a solution for my "logged in user" problem. My flow has a start action that executes the following:

ServletExternalContext externalContext = (ServletExternalContext) context.getExternalContext();
context.getFlowScope().put("user", externalContext.getRequest().getUserPrincipal());

When I need the user to invoke one of my services, I just declare an action like this:

<action bean="mailService" method="getInbox(${flowScope.user.name})" resultName="mails" resultScope="flow" />

Is there a solution more elegant than this? I need the user for just every service call, because I check for authorization in the service. I am beginning to think of putting the user into a ThreadLocal in a ServletFilter, so I do not have to deal with it in the presentation tier.

Keith Donald
Apr 9th, 2006, 12:26 PM
A flow execution listener might be a good bet for you.

Request scope still exists; see RequestContext.getRequestScope().

Keith

Goonie
Apr 10th, 2006, 04:27 AM
A flow execution listener might be a good bet for you.

What's the most elegant way to add a flow execution listener to a Flow(Execution(Impl))? Is there any declarative way (via XML descriptor)?

Christian Dupuis
Apr 10th, 2006, 10:45 AM
What's the most elegant way to add a flow execution listener to a Flow(Execution(Impl))? Is there any declarative way (via XML descriptor)?

You wanna try the following xml snippet. Basically you define a ListenerLoader in your RepositoryFactory:


<!-- Creates, saves, and restores managed flow executions -->
<bean id="repositoryFactory" class="org.springframework.webflow.execution.repository.c ontinuation.ContinuationFlowExecutionRepositoryFac tory">
<constructor-arg ref="flowRegistry"/>
<property name="listenerLoader">
<bean class="org.springframework.webflow.executor.ConditionalFl owExecutionListenerLoader">
<property name="listenerMap">
<map>
<entry>
<key>
<bean class="<your listener impl here>"/>
</key>
<value><the flowId of the flow the listener should get applied></value>
</entry>
</map>
</property>
</bean>
</property>
</bean>


Cheers
Christian