What Spring Web Flow Offers JSF Developers

Spring Web Flow, much like the Spring Framework itself, is a unique integration technology. Most of our users view it as a generic ApplicationController that can be embedded in any environment. We support Servlet and Portlet based applications, and ship integration with the leading web frameworks Struts, Spring MVC, and Java Server Faces. There are even teams I know of using Spring Web Flow in a Flex environment. In each of these environments, Spring Web Flow integrates to provide a better model for implementing navigation logic and managing application state.
Our users like this because they get to write their control flow once and reuse it anywhere. In this day of come-and-go web frameworks, Spring Web Flow provides them one modern framework to learn and build knowledge, tools, and extensions around. It has been designed to play this role from the beginning, and I am really excited to see Web Flow integration growing on a number of levels.
One important area where our integration is growing is with the Java Server Faces (JSF) community. Beginning with Spring Web Flow 1.0.3, our JSF integration is on-par with what the Spring community expects, and delivers what JSF developers in the trenches need most. This blog will illustrate the integration enhancements to show you the difference Spring Web Flow is making for JSF developers.
The Fit
Spring Web Flow is a controller framework that provides a language and runtime for implementing user interface control flow in a web application. Java Server Faces is a user interface component framework that consists of a standard API and two implementations - the Sun Reference Implementation and Apache MyFaces. As a standard API specification backed by the JCP, JSF provides extension points that allow product vendors to plug in and compete on their extensions. When used as a JSF extension, Spring Web Flow takes over two responsibilities: handling your view navigation rules and managing the state associated with your ongoing user interactions (a.k.a conversations). This integration combines Web Flow's strengths in navigation and state management with JSF's strength as a growing ecosystem of user interface component libaries. All JSF components and views continue to work as before with Web Flow in the picture. With Web Flow in there, JSF developers benefit from a considerably more powerful navigation model that alleviates the headaches traditionally associated with managing conversational state manually.
I could go on-and-on about Web Flow's specific feature set. Instead of doing that, I'll try and highlight the features that make the most difference for JSF developers.
In the domain of navigation handling Web Flow provides:
- The ability to implement dynamic navigation rules that are changeable on-the-fly without a server restart
- Full forward, backward, refresh, redirect, and recursive navigation capabilities built into its flow definition language
- Modularization and encapsulation of navigation logic through the flow definition concept
Basically, Web Flow solves every problem this poor soul experienced with JSF's basic navigation capabilities. As one of our leading users noted, Web Flow can be used as a complete replacement for JSF's default "forward-centric" navigation model:
Jeremy Grelle: I have been using SWF as a complete replacement for JSF navigation-rules, even in the case of our simpler pages and menus. I was happy to be able to take it to this extreme as it would be a bit too confusing for my team to have navigation rules defined in multiple places.
In the domain of state management, Web Flow introduces several conversational scopes that compliment JSF's existing request, session, and application scopes. These scopes are
- Conversation scope - a managed scope that lives for the duration of an user dialog
- Flow scope - a managed scope that lives for the duration of a flow executing within a conversation
- Flash scope - a managed scope that lives for the duration of a view participating in a flow
These scopes are 'managed' because they are cleaned up for you by Web Flow automatically. Conversation scope is ideal for storing model state to be persisted at the end of a user interaction such as an account registration wizard. Flash scope has proven quite useful to users integrating Ajax libraries such as Ajax4JSF and ICEFaces where multiple requests from the same view are the norm. In this case, flash scope allows model state to be manipulated across fine-grained Ajax requests coming from the same page and then automatically cleared on the next navigation.
Going back to what our leading users are saying:
Jeremy Grelle: I find that even with the simpler pages in JSF, you oftentimes need something to manage the state of your model across multiple requests to the page…there are many solutions for this problem in the JSF community (Tomahawk's saveState tag, Shale's dialog framework, etc.), but I personally find SWF's multiple scopes to be the most robust and elegant solution.
The Approach
Hopefully by now you have a good idea of what Web Flow brings to the table when used as a JSF extension. Now I'd like to go into a little more detail about how the integration works, and then close by showing you how to get starting using Web Flow and JSF together.
Understanding how Web Flow plugs in to JSF first takes a understanding of basic Web Flow constructs. The unit of controller functionality in Spring Web Flow - something like an Account registration wizard or a Customer Master/Detail Editor - is called a flow definition. A runtime instance of such a controller is called a flow execution. A new flow execution is launched at runtime to allow a single user to participate in a dialog with the application. The flow execution handles selecting the user's initial view, then responds to user events to carry out application behaviors and determine the next views to display. It also manages the state associated with the user dialog.
A big part of integrating Web Flow with JSF was fitting its flow execution lifecycle into the JSF lifecycle. This was achieved in part by implementing a custom PhaseListener that handles launching new flow executions when requested by a clients, as well as restoring existing flow executions during the restoration of JSF views.
For example, by accessing a URL like:
… you would start a new "register-account-flow". The request hits the FacesServlet first which kicks off the JSF lifecycle. Before any view is restored, the FlowPhaseListener starts the 'register-account-flow' which ultimately determines the initial JSF view to display.
Once the initial JSF view has been selected it is rendered. Rendering typically happens after an automatic redirect with Spring Web Flow's default always redirect on pause setting, which associates the selected view with a URL that can be safely refreshed and navigated back to at later point with no browser warnings.
When rendering does occur, JSF UI components have full access to beans managed in any of Web Flow's conversational scopes, as well as access to your standard JSF session and application scopes. Component value bindings are transparent, meaning that JSF view developers don't need to know which scope a bean is managed in, they only need to know the name of the bean. This capability was achieved by implementing another JSF extension point, a custom VariableResolver.
After a view participating in a flow execution has rendered, the user decides what she wants to do. If she decides to click the browser refresh button, that's fine - the flow execution is refreshed at its stable URL and the same JSF view is re-rendered. If she decides to do something that fires off some Ajax request from the same page, that's fine as well - the flow execution is again restored automatically, and JSF components participating in the Ajax call can update flow-managed state in a thread-safe manner seamlessly (no pun intended).
Once the user decides to invoke a UI command, for example by clicking a command link, the standard JSF postback lifecycle kicks in. After UI component validations are processed and model values are updated, the JSF action outcome is signaled as an event against the view-state of the restored flow execution. The flow takes over from there, processing the event by invoking the appropriate application behavior and selecting the next view according to the navigation rules of the flow definition. This Web Flow navigation step is handled by the last key construct in the JSF integration, a custom NavigationHandler.
To summarize, from the point of view of the JSF view and component developer, it's just standard JSF - doesn't matter whether you are using JSP or Facelets with XYZ component provider. Web Flow executions are restored for you automatically and access to conversatioal state is completely transparent. Web Flow events are just standard JSF UI command outcomes. From the perspective of the controller developer, it's all Web Flow. As a result, verbose and limited navigation rules in faces-config.xml are replaced by modular, concise flow definitions based on a much richer flow definition language. The bottom line is you get all the advantages of the native JSF component model with all the strengths of the Web Flow navigation model.
Getting Started
The best way to get started with Spring Web Flow in a JSF environment is to download the 1.0.3 release and deploy the sellitem-jsf sample, which is also available for testing on-line. The sample is importable as an Eclipse Dynamic Web Project for easy deployment inside Eclipse. In addition, the sample is Spring IDE 2.0 enabled, which is an Eclipse plugin that includes a Graphical Web Flow Editor.
I'll briefly highlight getting started with Web Flow in a JSF environment with the sellitem-jsf sample to close out this entry.
Setting up the Faces Config (Boilerplate)
To plug Web Flow in the custom integration artifacts discussed above must be added to faces-config.xml:
<navigation-handler>org.springframework.webflow.executor.jsf.FlowNavigationHandler</navigation-handler>
<variable-resolver>org.springframework.webflow.executor.jsf.DelegatingFlowVariableResolver</variable-resolver>
</application>
<lifecycle>
<phase-listener>org.springframework.webflow.executor.jsf.FlowPhaseListener</phase-listener>
</lifecycle>
Writing Your Flow Definitions (Meat)
Then you need your flow definitions that define your controller logic. This is the "sellitem" flow definition, which is a 4-step checkout flow with a single dynamic navigation rule that ultimately ends with confirmed sale transaction:
<flow xmlns="http://www.springframework.org/schema/webflow"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/webflow
http://www.springframework.org/schema/webflow/spring-webflow-1.0.xsd">
<var name="sale" class="org.springframework.webflow.samples.sellitem.Sale" scope="conversation" />
<start-state idref="enterPriceAndItemCount" />
<view-state id="enterPriceAndItemCount" view="/priceAndItemCountForm.jsp">
<transition on="submit" to="enterCategory"/>
</view-state>
<view-state id="enterCategory" view="/categoryForm.jsp">
<transition on="submit" to="requiresShipping" />
</view-state>
<decision-state id="requiresShipping">
<if test="${conversationScope.sale.shipping}" then="enterShippingDetails" else="processSale" />
</decision-state>
<view-state id="enterShippingDetails" view="/shippingDetailsForm.jsp">
<transition on="submit" to="processSale" />
</view-state>
<action-state id="processSale">
<bean-action bean="saleProcessor" method="process">
<method-arguments>
<argument expression="conversationScope.sale" />
</method-arguments>
</bean-action>
<transition on="success" to="showCostOverview" />
</action-state>
<end-state id="showCostOverview" view="/costOverview.jsp" />
</flow>
Setting Up the Web Flow Config (Boilerplate)
The flow definitions should be registered in a registry so they are eligible for execution:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:flow="http://www.springframework.org/schema/webflow-config"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/webflow-config
http://www.springframework.org/schema/webflow-config/spring-webflow-config-1.0.xsd">
<!– Launches, continues, and refreshes flow executions –>
<flow:executor id="flowExecutor" registry-ref="flowRegistry"/>
<!– Creates the registry of flow definitions eligible for execution in this application –>
<flow:registry id="flowRegistry">
<flow:location path="/WEB-INF/flows/sellitem-flow.xml" />
</flow:registry>
</beans>
Launching a Flow Execution
Once registered, launch a flow simply by pointing your browser at the FacesServlet with the flow identifier provided as input:
It is worth noting you can configure the format of flow definition and execution URLs - for example, to turn on REST-style URLs instead of the default request-parameter based URLs.
Implementing the JSF views
As discussed JSF views are just plain JSF views whether they are JSP-based or Facelet-based, with standard JSF binding expressions for accessing conversational state and standard UI commands for signaling Web Flow events. The sellitem-jsf sample uses JSPs-based views:
<div id="content">
<h2>Enter price and item count</h2>
<hr>
<table>
<h:form id="priceAndItemCountForm">
<tr>
<td>Price:</td>
<td>
<h:inputText id="price" value="#{sale.price}" required="true">
<f:validateDoubleRange minimum="0.01"/>
</h:inputText>
</td>
<td>
<h:message for="price" errorClass="error"/>
</td>
</tr>
<tr>
<td>Item count:</td>
<td>
<h:inputText id="itemCount" value="#{sale.itemCount}" required="true">
<f:validateLongRange minimum="1"/>
</h:inputText>
</td>
<td>
<h:message for="itemCount" errorClass="error"/>
</td>
</tr>
<tr>
<td colspan="2" class="buttonBar">
<h:commandButton type="submit" value="Next" action="submit"/>
</td>
<td></td>
</tr>
</h:form>
</table>
</div>
</f:view>
That's it! You can try out the application and see for yourself how Web Flow cares for navigation and application controller logic, while JSF UI components care for content rendering and data binding and validation behavior. It really is a great fit.
Future
We didn't just get here by accident, we got here by working with clients building applications with Spring Web Flow and JSF everyday on our forums and support centers. Special thanks go out to Jeremy Grelle, James Clinton, Ed Burns, Craig McClanahan, and Colin Sampaleanu for all their contributions in getting the Spring Web Flow JSF integration to where it is today - rock solid.
Work on Spring Web Flow 1.1 has begun, and greater levels of integration is a major theme in an exciting roadmap. Notable on the JSF front, we will be adding support for the Unified Expression Language (EL) within flow definitions, as well as support for leveraging Spring 2.0 as a comprehensive provider of JSF managed-beans beans across all scopes - including the conversational scopes provided by Spring Web Flow. This work is in addition to new core features that will benefit Web Flow users in all environments, such as support for conversation scoped persistence contexts. Participate in the 1.1 Roadmap discussion on the forums for more information and to get involved!
I'd also like to take this opportunity to encourage those already using Spring Web Flow in a JSF environment to speak out about your experience–send me an email, leave a comment here, write an article on JSF central, tell leaders in the JSF community about your experience. Your real world experience can help influence the direction of the JSF 2.0 specification in a time where the specification lead has asked for community feedback. Interface21 has been extended an invitation from Ed Burns, the JSF specification lead, to be a part of the JSF 2.0 expert group, which is a recognition of Web Flow's contribution as an innovative JSF extension. We have accepted that invitation and are excited about helping channel whats proven to work in the area of navigation and state management on a general basis back into JSF 2.0, while continuing to chart new territory and remaining usable in any environment.
Modified

Erwin Vervaet says:
Added on April 22nd, 2007 at 2:58 amGreat entry Keith!
One small clarification:
Flow scope doesn't live the life of a flow execution but rather a flow session inside a flow execution. For instance a subflow has a seperate flow scope from it's parent flow, even though they participate in the same flow execution.
Erwin
Jan says:
Added on April 22nd, 2007 at 4:04 amHi - having experimented with JSF a couple of weeks, I get the feeling JSF doesn't fulfill all my web developments needs and in some areas simply isn't good enough. JSF only provides a basic infrastructure and obviously needs help…, so I've been looking at JBoss Seam lately. This framework also allows kind of a flow definition to support a web conversation. Is this comparable to what Spring Web Flow brings to the table?
Yagiz Erkan says:
Added on April 23rd, 2007 at 4:51 pm> seamlessly (no pun intended)
Excellent!
Jan says:
Added on April 25th, 2007 at 4:01 pm>>> seamlessly (no pun intended)
>Excellent!
Yeah, great joke (NOT!)
I'm guessing serious questions, don't get answered on this blog then…?
Alexandre Poitras says:
Added on April 25th, 2007 at 4:12 pmHi Kieth,
First of, thank for the wonderful entry. Very interesting.
I just have one small question. You state in your introduction that "Most of our users view it as a generic ApplicationController that can be embedded in any environment." which is something I totally agree with. On the other hand, in the webflow reference manual it's written "SWF is a powerful controller framework based on a finite-state machine, fully addressing the "C" in MVC". I don't want to be a hard ass here but I think this sentence is misleading. There is a big difference between the input controller in MVC and an application controller even though they are quite linked together. Wouldn't it be better in the documentation to state that Web flow is an application controller therefore reducing (or eliminating) necessary code needed to implemented a Struts action, a JSF event listener, … It may be not important but I'm so tired to see the MVC pattern misquoted and it makes it hard to explain what is Web Flow to new developers.
Ben Hale (blog author) says:
Added on April 25th, 2007 at 4:56 pmActually Keith has been on vacation for the last couple of days. I'm sure that he'll answer your questions as soon as he gets back.
Andres b says:
Added on April 30th, 2007 at 11:27 amWhile testing the app, I am getting an Exception (report below).
How to reproduce it:
Go for a sell, and don't click on shipping. Go to the last page where the "home" button appears. Click your browser back-button to the Select Category page. Then click Next and the exception is thrown.
Regards
Andres B
——————————–
type Exception report
message
description The server encountered an internal error () that prevented it from fulfilling this request.
exception
javax.servlet.ServletException: No flow execution could be found with key '_c56047578-BAE4-56D6-1DEF-D0A2C4FD032C_k77AD2F89-042A-DE38-721E-3CEB13BCB703' — perhaps this executing flow has ended or expired? This could happen if your users are relying on browser history (typically via the back button) that references ended flows.; nested exception is org.springframework.webflow.conversation.NoSuchConversationException: No conversation could be found with id '56047578-BAE4-56D6-1DEF-D0A2C4FD032C' — perhaps this conversation has ended?
javax.faces.webapp.FacesServlet.service(FacesServlet.java:152)
root cause
org.springframework.webflow.execution.repository.NoSuchFlowExecutionException: No flow execution could be found with key '_c56047578-BAE4-56D6-1DEF-D0A2C4FD032C_k77AD2F89-042A-DE38-721E-3CEB13BCB703' — perhaps this executing flow has ended or expired? This could happen if your users are relying on browser history (typically via the back button) that references ended flows.; nested exception is org.springframework.webflow.conversation.NoSuchConversationException: No conversation could be found with id '56047578-BAE4-56D6-1DEF-D0A2C4FD032C' — perhaps this conversation has ended?
org.springframework.webflow.execution.repository.support.AbstractConversationFlowExecutionRepository.getConversation(AbstractConversationFlowExecutionRepository.java:246)
org.springframework.webflow.execution.repository.support.AbstractConversationFlowExecutionRepository.getLock(AbstractConversationFlowExecutionRepository.java:125)
org.springframework.webflow.executor.jsf.FlowExecutionKeyStateHolder.restoreFlowExecution(FlowExecutionKeyStateHolder.java:122)
org.springframework.webflow.executor.jsf.FlowExecutionKeyStateHolder.restoreState(FlowExecutionKeyStateHolder.java:109)
javax.faces.component.UIComponentBase.processRestoreState(UIComponentBase.java:728)
javax.faces.component.UIComponentBase.processRestoreState(UIComponentBase.java:719)
org.apache.myfaces.application.jsp.JspStateManagerImpl.restoreComponentState(JspStateManagerImpl.java:221)
org.apache.myfaces.application.jsp.JspStateManagerImpl.restoreView(JspStateManagerImpl.java:287)
org.apache.myfaces.application.jsp.JspViewHandlerImpl.restoreView(JspViewHandlerImpl.java:255)
org.apache.myfaces.lifecycle.LifecycleImpl.restoreView(LifecycleImpl.java:141)
org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:66)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:137)
Andres B says:
Added on April 30th, 2007 at 11:33 amWriting this for the second time, so I'll make it short.
The ref app throws an exception when going back to the Category Page and clicking next. Go back to that page BEFORE clicking the HOME button in the last page of the flow.
Note (added): trying to reproduce the error I'm getting strange behavior on the app. After clicking on a button, it is not taking me to the next page.[started the app again, but couldn't reproduce this last error]
Regards
Andres B.
—-
type Exception report
message
description The server encountered an internal error () that prevented it from fulfilling this request.
exception
javax.servlet.ServletException: No flow execution could be found with key '_c76D1DB42-9439-13FC-9B8B-3C0AE6248C99_k447197EC-1A3F-51C0-F7BD-722E71E172DB' — perhaps this executing flow has ended or expired? This could happen if your users are relying on browser history (typically via the back button) that references ended flows.; nested exception is org.springframework.webflow.conversation.NoSuchConversationException: No conversation could be found with id '76D1DB42-9439-13FC-9B8B-3C0AE6248C99' — perhaps this conversation has ended?
javax.faces.webapp.FacesServlet.service(FacesServlet.java:152)
root cause
org.springframework.webflow.execution.repository.NoSuchFlowExecutionException: No flow execution could be found with key '_c76D1DB42-9439-13FC-9B8B-3C0AE6248C99_k447197EC-1A3F-51C0-F7BD-722E71E172DB' — perhaps this executing flow has ended or expired? This could happen if your users are relying on browser history (typically via the back button) that references ended flows.; nested exception is org.springframework.webflow.conversation.NoSuchConversationException: No conversation could be found with id '76D1DB42-9439-13FC-9B8B-3C0AE6248C99' — perhaps this conversation has ended?
org.springframework.webflow.execution.repository.support.AbstractConversationFlowExecutionRepository.getConversation(AbstractConversationFlowExecutionRepository.java:246)
org.springframework.webflow.execution.repository.support.AbstractConversationFlowExecutionRepository.getLock(AbstractConversationFlowExecutionRepository.java:125)
org.springframework.webflow.executor.jsf.FlowExecutionKeyStateHolder.restoreFlowExecution(FlowExecutionKeyStateHolder.java:122)
org.springframework.webflow.executor.jsf.FlowExecutionKeyStateHolder.restoreState(FlowExecutionKeyStateHolder.java:109)
javax.faces.component.UIComponentBase.processRestoreState(UIComponentBase.java:728)
javax.faces.component.UIComponentBase.processRestoreState(UIComponentBase.java:719)
org.apache.myfaces.application.jsp.JspStateManagerImpl.restoreComponentState(JspStateManagerImpl.java:221)
org.apache.myfaces.application.jsp.JspStateManagerImpl.restoreView(JspStateManagerImpl.java:287)
org.apache.myfaces.application.jsp.JspViewHandlerImpl.restoreView(JspViewHandlerImpl.java:255)
org.apache.myfaces.lifecycle.LifecycleImpl.restoreView(LifecycleImpl.java:141)
org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:66)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:137)
Ben Hale (blog author) says:
Added on April 30th, 2007 at 1:19 pm[quote post="149"]The ref app throws an exception when going back to the Category Page and clicking next. Go back to that page BEFORE clicking the HOME button in the last page of the flow.[/quote]
Are you trying to use the back button from the end confirmation page? Because the failure you're seeing would be by design there. To prevent duplicate submit behavior, when the end of a flow is reached, the FlowExecution (identified by the key) is removed from the storage repository.
You should be able to go backwards and forwards while the flow has not ended, but once you get to the 'end', you can't navigate any more.
cyber sammy says:
Added on May 8th, 2007 at 8:25 amHi Jan,
I am also trying to compare SEAM and Spring.
cs.
diya says:
Added on May 29th, 2007 at 4:26 amCan we use Spring MVC in WebFlow???
Nick says:
Added on June 28th, 2007 at 6:33 pmWell I'm disappointed based on just using the sample app, I enter the item price and the number of items, click next, then select cat A, click next, then I decide that I actually want to go back and get the items delivered. I hit the browser back button, check the check box for shipping, click next and boom, nasty stack trace. I tried seam a while ago and always got the same problem, sometimes using the back button worked and other times it didnt, it never seemed robust.
Stack Trace:
javax.servlet.ServletException: No flow execution could be found with key '_c48421F40-2A41-0352-263E-9B5AA888FF09_k70AFB41A-3C3C-AE5D-A112-BC4C16A5AF21' — perhaps this executing flow has ended or expired? This could happen if your users are relying on browser history (typically via the back button) that references ended flows.; nested exception is org.springframework.webflow.conversation.NoSuchConversationException: No conversation could be found with id '48421F40-2A41-0352-263E-9B5AA888FF09' — perhaps this conversation has ended?
javax.faces.webapp.FacesServlet.service(FacesServlet.java:152)
org.springframework.webflow.executor.jsf.FlowSystemCleanupFilter.doFilterInternal(FlowSystemCleanupFilter.java:41)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:75)
root cause
org.springframework.webflow.execution.repository.NoSuchFlowExecutionException: No flow execution could be found with key '_c48421F40-2A41-0352-263E-9B5AA888FF09_k70AFB41A-3C3C-AE5D-A112-BC4C16A5AF21' — perhaps this executing flow has ended or expired? This could happen if your users are relying on browser history (typically via the back button) that references ended flows.; nested exception is org.springframework.webflow.conversation.NoSuchConversationException: No conversation could be found with id '48421F40-2A41-0352-263E-9B5AA888FF09' — perhaps this conversation has ended?
org.springframework.webflow.execution.repository.support.AbstractConversationFlowExecutionRepository.getConversation(AbstractConversationFlowExecutionRepository.java:242)
org.springframework.webflow.execution.repository.support.AbstractConversationFlowExecutionRepository.getLock(AbstractConversationFlowExecutionRepository.java:121)
org.springframework.webflow.executor.jsf.FlowExecutionKeyStateHolder.restoreFlowExecution(FlowExecutionKeyStateHolder.java:124)
org.springframework.webflow.executor.jsf.FlowExecutionKeyStateHolder.restoreState(FlowExecutionKeyStateHolder.java:111)
javax.faces.component.UIComponentBase.processRestoreState(UIComponentBase.java:728)
javax.faces.component.UIComponentBase.processRestoreState(UIComponentBase.java:719)
org.apache.myfaces.application.jsp.JspStateManagerImpl.restoreComponentState(JspStateManagerImpl.java:221)
org.apache.myfaces.application.jsp.JspStateManagerImpl.restoreView(JspStateManagerImpl.java:287)
org.apache.myfaces.application.jsp.JspViewHandlerImpl.restoreView(JspViewHandlerImpl.java:255)
org.apache.myfaces.lifecycle.LifecycleImpl.restoreView(LifecycleImpl.java:141)
org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:66)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:137)
org.springframework.webflow.executor.jsf.FlowSystemCleanupFilter.doFilterInternal(FlowSystemCleanupFilter.java:41)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:75)
root cause
org.springframework.webflow.conversation.NoSuchConversationException: No conversation could be found with id '48421F40-2A41-0352-263E-9B5AA888FF09' — perhaps this conversation has ended?
org.springframework.webflow.conversation.impl.ConversationContainer.getConversation(ConversationContainer.java:114)
org.springframework.webflow.conversation.impl.SessionBindingConversationManager.getConversation(SessionBindingConversationManager.java:122)
org.springframework.webflow.execution.repository.support.AbstractConversationFlowExecutionRepository.getConversation(AbstractConversationFlowExecutionRepository.java:239)
org.springframework.webflow.execution.repository.support.AbstractConversationFlowExecutionRepository.getLock(AbstractConversationFlowExecutionRepository.java:121)
org.springframework.webflow.executor.jsf.FlowExecutionKeyStateHolder.restoreFlowExecution(FlowExecutionKeyStateHolder.java:124)
org.springframework.webflow.executor.jsf.FlowExecutionKeyStateHolder.restoreState(FlowExecutionKeyStateHolder.java:111)
javax.faces.component.UIComponentBase.processRestoreState(UIComponentBase.java:728)
javax.faces.component.UIComponentBase.processRestoreState(UIComponentBase.java:719)
org.apache.myfaces.application.jsp.JspStateManagerImpl.restoreComponentState(JspStateManagerImpl.java:221)
org.apache.myfaces.application.jsp.JspStateManagerImpl.restoreView(JspStateManagerImpl.java:287)
org.apache.myfaces.application.jsp.JspViewHandlerImpl.restoreView(JspViewHandlerImpl.java:255)
org.apache.myfaces.lifecycle.LifecycleImpl.restoreView(LifecycleImpl.java:141)
org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:66)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:137)
org.springframework.webflow.executor.jsf.FlowSystemCleanupFilter.doFilterInternal(FlowSystemCleanupFilter.java:41)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:75)
Keith Donald (blog author) says:
Added on June 28th, 2007 at 6:43 pmHi Nick,
That exception is expected *consistently* at that time because you completed the flow (it submitted a order on the backend and then ended) then attempted to go back and resume it after completion. Once a flow has ended, it cannot be resumed - a new, independnt flow execution must be started. Please review the flow definition and you will see this code which ends the flow by entering the costOverview end-state after processing the sale.
Now in a real application you should handle this exception and route to an error page or restart the flow mind you…
HTH,
Keith
Johan Eltes says:
Added on July 3rd, 2007 at 3:03 pmIs there a sample for using JSF SWF JSP/Facelets to implement a JSR 168 portlet? Previously, it was only possible with SWT Spring MVC view technology, wasn't it? Would be great if SWF/JSF also works for portlets.
Siarhei says:
Added on July 4th, 2007 at 9:15 am[quote comment="22036"]Hi Jan,
I am also trying to compare SEAM and Spring.
cs.[/quote]
IMHO, if you use Seam you don't necessarily need Spring, although Spring does offer some functionality that is not in Seam scope. The more I observe developments within Spring the more I get an impressions that the choice between Seam and Spring is more becoming emotionally than technically based…
Vijay says:
Added on July 6th, 2007 at 7:56 pmHi,
I want to use JSF managed beans inside the Spring web flow webflow.xml ? How do I do that ? Your example has "sale" being used within the JSF page. I already have a working JSF application and just want to remove the navigation from the faces-config.xml from it to the webflow.xml ? Is that possible ?
http://forum.springframework.org/showthread.php?t=37781
TIA,
Vijay
mike says:
Added on July 10th, 2007 at 5:48 amAre there any default ways of handling exceptions such as:
WARNING: phase(RESTORE_VIEW 1,com.sun.faces.context.FacesContextImpl@135019d) threw exception: org.springframework.webflow.execution.repository.NoSuchFlowExecutionException: No flow execution could be found with key '_cD8DA1EA5-D-FAD0-030C-04FECE3CDF07_kDC9F835A-0074-A5A7-1D96-18F474F9D7C8' — perhaps this executing flow has ended or expired? This could happen if your users are relying on browser history (typically via the back button) that references ended flows.; nested exception is org.springframework.webflow.conversation.NoSuchConversationException: No conversation could be found with id 'D8DA1EA5-D-FAD0-030C-04FECE3CDF07' — perhaps this conversation has ended? No flow execution could be found with key '_cD8DA1EA5-D-FAD0-030C-04FECE3CDF07_kDC9F835A-0074-A5A7-1D96-18F474F9D7C8' — perhaps this executing flow has ended or expired? This could happen if your users are relying on browser history (typically via the back button) that references ended flows.; nested exception is org.springframework.webflow.conversation.NoSuchConversationException: No conversation could be found with id 'D8DA1EA5-D-FAD0-030C-04FECE3CDF07' — perhaps this conversation has ended?
All i get there is a 404 !?
And btw. can i suppress the direct navigation to e.g. some parts of the flow - as errors might happen if some beans are not initialized correctly beforehand?
THX,
Mike
Mike says:
Added on July 10th, 2007 at 6:08 amHi,
is there any default exception handling for cases like:
org.springframework.webflow.conversation.NoSuchConversationException: No conversation could be found with id 'AFC13920-3DE9-A248-AB8F-C53D6ED25AA0' — perhaps this conversation has ended?
e.g. redirect the user to the flow start…etc.?
And is it possible to prevent users from starting in the middle of a flow by selecting the page-uri directly?
THX,
Mike
peter says:
Added on July 14th, 2007 at 3:25 am�外写的�错�
Martin Jozef says:
Added on September 27th, 2007 at 8:28 amI am trying web-flow with RichFaces instead of MyFaces.
Should i expect different behavior with Web-flow between the two?
I noticed on your sellitem example the url contains intro.faces?_flowExecutionKey= ……
but when i use RichFaces that's not the case.
Mahesh Nanavate says:
Added on November 12th, 2007 at 5:38 pmhow can we re-direct the user to a proper error message when he presses browser back button from an end-state view instead of displaying a server side error ?
David Pereira says:
Added on November 13th, 2007 at 3:46 pmMahesh, you can customize the error page for this exception in your web.xml
org.springframework.webflow.conversation.NoSuchConversationException
/myCustomErrorPage.jsp
Any other suggestion?
David Pereira says:
Added on November 13th, 2007 at 3:50 pmCorrecting my previous post:
<error-page>
<exception-type>org.springframework.webflow.conversation.NoSuchConversationException</exception-type>
<location>/myCustomErrorPage.jsp</location>
</error-page>
David says:
Added on July 11th, 2008 at 3:23 amhi there,
i'm using jsf, swf and spring and encountered a problem i can't handle.
it is probably a simple one. i understand that the only way to change from one state (view state) to another is using a form submit that the swf handles using the i don't have a submit option. for example, when i want to move from one tab to another (and change the state accordingly) i cant find the way to do it. can you guide me?
thanks so much,
David