Feedback requested: Redirect support in SWF
We have extended/refined the support for redirects in Spring Web Flow; feedback on these refinements are much appreciated.
1.0 introduced 3 redirect types: quot;conversation redirectquot;, quot;flow redirectquot;, and quot;external redirectquot;.
A conversation redirect allows redirect to the *current* (most recent) view-state of a conversation, at a single conversation ucl, while the conversation remains active.
A flow redirect requests that a entirely new execution of another flow be launched--used to support flow chaining and restart use cases.
A external redirect redirects to an arbitrary external ucl, with support for sending a flow execution key through the redirect.
1.0 RC1 introduces a 4th type, called a quot;flow execution redirectquot;. This supports redirecting to *any* previously traversed view-state of a flow execution at a unique quot;flow execution uclquot;, to support post-gt;redirect-gt;get semantics with full support for back, forward, and refresh buttons while the conversation remains active.
In addition, the semantics of quot;conversation redirectquot; and quot;flow execution redirectquot; are a bit different now--previously application view selections made by view states were cached through the redirect; now they're reconstituted via a new FlowExecution quot;refreshquot; operation on each redirect request. Note this causes any data in request scope of the request preceding the redirect to be lost (while data in flow scope is preserved of course).
quot;itemlistquot; and quot;numberguessquot; samples demonstrate the quot;conversation redirectquot; (notice how back doesn't make any sense as the ucl is stable throughout the flow, and it is best suited for a quot;SimpleFlowExecutionRepositoryquot;).
quot;sellitemquot; demonstrates the quot;flowExecutionRedirectquot;. Notice how the ucl changes on each submit and back/forward/refresh are fully supported. Also note how this is is suited for a quot;ContinuationFlowExecutionRepositoryquot; and does not make sense with client-side storage.
Notice how post-gt;redirect-gt;get semantics can be configured globally for all flows (see FlowExecutor.redirectOnPause property) or on a per flow basis (see view-state redirect prefixes in quot;viewquot; attribute DTD). Of course, redirection is optional, and samples like Phonebook don't do any redirects, relying on continuations + page caching to get stable navigation button behavior.
Thoughts? We should release 1.0 RC1 once we are confident these remaining redirect challenges are right.
Keith
Hey, Keith,
Just a question. In the description of sellitem, you mention that the quot;ucl changes on each submitquot;. Perhaps I'm using the wrong version of SWF (I'm on 1.0 EA) but I'm not seeing this. The ucl remains consistently swf-sellitem/p...lowId=sellitem.
Thanks,
Rob
Yes, this is new in 1.0 RC1. Try out a 4/30 or gt; nightly build:
do...pring-webflow/
Sounds excellent Keith and I look forward to trying it out asap.
Hi, Keith,
I was trying to run through the sellitem example but am encountering this exception when I try to start the flow (using Jetty6.0.0beta14):
Code:
2006-05-02 10:01:07,521 DEBUG [org..webflow.executor.support.FlowRequestHandler] - lt;Request initiated by [ServletExternalContext@290e1513 requestParameterMap = map['_flowId' -gt; 'sellitem']]gt;
:WARN: EXCEPTION
org..web.util.NestedServletException: Request processing failed; nested exception is java.lang.ArrayIndexOutOfBoundsException: 0
Caused by: java.lang.ArrayIndexOutOfBoundsException: 0 at org..webflow.ParameterMap.get(ParameterMap.java:144) at org..webflow.ParameterMap.get(ParameterMap.java:128) at org..webflow.executor.support.FlowExecutorArgumentExtractor.extractFlowExecutionKey(FlowExecutorArgumentExtractor.java:267) at org..webflow.executor.support.FlowRequestHandler.handleFlowRequest(FlowRequestHandler.java:100) at org..webflow.executor.mvc.FlowController.handleRequestInternal(FlowController.java:198) at org..web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:153) at org..web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:45) at org..web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:796) at org..web.servlet.DispatcherServlet.doService(DispatcherServlet.java:727) at org..web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:396) at org..web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:350) at javax.servlet.from.fromServlet.service(fromServlet.java:747) at javax.servlet.from.fromServlet.service(fromServlet.java:860) at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:423) at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:350) at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:221) at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:539) at org.mortbay.jetty.Server.handle(Server.java:341) at org.mortbay.jetty.Server.handle(Server.java:311) at org.mortbay.jetty.fromConnection.doHandler(fromConnection.java:355) at org.mortbay.jetty.fromConnection.access$1500(fromConnection.java:38) at org.mortbay.jetty.fromConnection$RequestHandler.headerComplete(fromConnection.java:598) at org.mortbay.jetty.fromParser.parseNext(fromParser.java:487) at org.mortbay.jetty.fromParser.parseAvailable(fromParser.java:196) at org.mortbay.jetty.fromConnection.handle(fromConnection.java:293) at org.mortbay.jetty.nio.SelectChannelConnector$fromEndPoint.run(SelectChannelConnector.java:710) at org.mortbay.thread.BoundedThreadPool$PoolThread.run(BoundedThreadPool.java:412)
:WARN: Nested in org..web.util.NestedServletException: Request processing failed; nested exception is java.lang.ArrayIndexOutOfBoundsException: 0:
java.lang.ArrayIndexOutOfBoundsException: 0 at org..webflow.ParameterMap.get(ParameterMap.java:144) at org..webflow.ParameterMap.get(ParameterMap.java:128) at org..webflow.executor.support.FlowExecutorArgumentExtractor.extractFlowExecutionKey(FlowExecutorArgumentExtractor.java:267) at org..webflow.executor.support.FlowRequestHandler.handleFlowRequest(FlowRequestHandler.java:100) at org..webflow.executor.mvc.FlowController.handleRequestInternal(FlowController.java:198) at org..web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:153) at org..web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:45) at org..web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:796) at org..web.servlet.DispatcherServlet.doService(DispatcherServlet.java:727) at org..web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:396) at org..web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:350) at javax.servlet.from.fromServlet.service(fromServlet.java:747) at javax.servlet.from.fromServlet.service(fromServlet.java:860) at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:423) at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:350) at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:221) at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:539) at org.mortbay.jetty.Server.handle(Server.java:341) at org.mortbay.jetty.Server.handle(Server.java:311) at org.mortbay.jetty.fromConnection.doHandler(fromConnection.java:355) at org.mortbay.jetty.fromConnection.access$1500(fromConnection.java:38) at org.mortbay.jetty.fromConnection$RequestHandler.headerComplete(fromConnection.java:598) at org.mortbay.jetty.fromParser.parseNext(fromParser.java:487) at org.mortbay.jetty.fromParser.parseAvailable(fromParser.java:196) at org.mortbay.jetty.fromConnection.handle(fromConnection.java:293) at org.mortbay.jetty.nio.SelectChannelConnector$fromEndPoint.run(SelectChannelConnector.java:710) at org.mortbay.thread.BoundedThreadPool$PoolThread.run(BoundedThreadPool.java:412)
:WARN: /swf-sellitem/pos.htm:
java.lang.ArrayIndexOutOfBoundsException: 0 at org..webflow.ParameterMap.get(ParameterMap.java:144) at org..webflow.ParameterMap.get(ParameterMap.java:128) at org..webflow.executor.support.FlowExecutorArgumentExtractor.extractFlowExecutionKey(FlowExecutorArgumentExtractor.java:267) at org..webflow.executor.support.FlowRequestHandler.handleFlowRequest(FlowRequestHandler.java:100) at org..webflow.executor.mvc.FlowController.handleRequestInternal(FlowController.java:198) at org..web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:153) at org..web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:45) at org..web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:796) at org..web.servlet.DispatcherServlet.doService(DispatcherServlet.java:727) at org..web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:396) at org..web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:350) at javax.servlet.from.fromServlet.service(fromServlet.java:747) at javax.servlet.from.fromServlet.service(fromServlet.java:860) at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:423) at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:350) at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:221) at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:539) at org.mortbay.jetty.Server.handle(Server.java:341) at org.mortbay.jetty.Server.handle(Server.java:311) at org.mortbay.jetty.fromConnection.doHandler(fromConnection.java:355) at org.mortbay.jetty.fromConnection.access$1500(fromConnection.java:38) at org.mortbay.jetty.fromConnection$RequestHandler.headerComplete(fromConnection.java:598) at org.mortbay.jetty.fromParser.parseNext(fromParser.java:487) at org.mortbay.jetty.fromParser.parseAvailable(fromParser.java:196) at org.mortbay.jetty.fromConnection.handle(fromConnection.java:293) at org.mortbay.jetty.nio.SelectChannelConnector$fromEndPoint.run(SelectChannelConnector.java:710) at org.mortbay.thread.BoundedThreadPool$PoolThread.run(BoundedThreadPool.java:412)
...
I'll try running under Tomcat next, but just thought you'd like to know.
Rob
What version?
What version of SWF?
Last night's build.
That is a bug. Will fix promptly and add a test case.
Keith
Fixed. Good catch; I'm not sure why this showed up in Jetty just now, as the bug has been there. It's resolved now. |