This turns out to be another problem with delegation support. There is a little section of code in the SpringFlowStateManager that decides if the view is restorable or not:
protected UIViewRoot restoreTreeStructure(FacesContext context, String viewId, String renderKitId) {
if (!JsfUtils.isFlowRequest())
{
return super.restoreTreeStructure(context, viewId, renderKitId);
}
RequestContext requestContext = RequestContextHolder.getRequestContext();
SerializedView view = (SerializedView) requestContext.getViewScope().get(SERIALIZED_VIEW_STATE);
if (view == null || !view.viewId.equals(viewId))
{ <--------------------------- (1)
logger.debug("No matching view in view scope");
return null;
}
The view.viewIdWith ICEFaces + webflow 2.0.3, the viewId is pre-constructed to contain the path to the resource. An example viewId in the ICEFaces Booking example is "/WEB-INF/flows/enterSearchCriteria.xhtml"
In Spring 2.0.5, the path is not added as part of the Flow startup and instead the FlowViewHandler does a little bit of work to flesh out the path information using a resource loader. This code is not present in 2.0.3. The FlowViewHandler is likely loaded from the faces-config.xml as ours is, but it ls loaded before ours. Since our ViewHandler doesn't delegate the code to fill out the path in the viewId is never executed. Hence the flow is continuously restarted.
A workaround is to define a Spring FlowViewHandler in the application faces-config.xml file. This has certain disadvantages like causing a duplicate FlowViewHandler instance to be created.
<application>
<view-handler>
com.sun.facelets.FaceletViewHandler
</view-handler>
<view-handler>
com.icesoft.faces.facelets.D2DFaceletViewHandler
</view-handler>
<!--#4200 define another Spring ViewHandler -->
<view-handler>
org.springframework.faces.webflow.FlowViewHandler
</view-handler>
<variable-resolver>org.springframework.web.jsf.DelegatingVariableResolver</variable-resolver>
</application>
This turns out to be another problem with delegation support. There is a little section of code in the SpringFlowStateManager that decides if the view is restorable or not:
protected UIViewRoot restoreTreeStructure(FacesContext context, String viewId, String renderKitId) {
{ return super.restoreTreeStructure(context, viewId, renderKitId); }if (!JsfUtils.isFlowRequest())
RequestContext requestContext = RequestContextHolder.getRequestContext();
{ <--------------------------- (1) logger.debug("No matching view in view scope"); return null; }SerializedView view = (SerializedView) requestContext.getViewScope().get(SERIALIZED_VIEW_STATE);
if (view == null || !view.viewId.equals(viewId))
The view.viewIdWith ICEFaces + webflow 2.0.3, the viewId is pre-constructed to contain the path to the resource. An example viewId in the ICEFaces Booking example is "/WEB-INF/flows/enterSearchCriteria.xhtml"
In Spring 2.0.5, the path is not added as part of the Flow startup and instead the FlowViewHandler does a little bit of work to flesh out the path information using a resource loader. This code is not present in 2.0.3. The FlowViewHandler is likely loaded from the faces-config.xml as ours is, but it ls loaded before ours. Since our ViewHandler doesn't delegate the code to fill out the path in the viewId is never executed. Hence the flow is continuously restarted.
A workaround is to define a Spring FlowViewHandler in the application faces-config.xml file. This has certain disadvantages like causing a duplicate FlowViewHandler instance to be created.
<application>
<view-handler>
com.sun.facelets.FaceletViewHandler
</view-handler>
<view-handler>
com.icesoft.faces.facelets.D2DFaceletViewHandler
</view-handler>
<!--#4200 define another Spring ViewHandler -->
<view-handler>
org.springframework.faces.webflow.FlowViewHandler
</view-handler>
<variable-resolver>org.springframework.web.jsf.DelegatingVariableResolver</variable-resolver>
</application>