Page 1 of 2 12 LastLast
Results 1 to 10 of 11

Thread: Solution to double form submit...

  1. #1
    Join Date
    Aug 2004
    Posts
    1,905

    Default Solution to double form submit...

    Hi all,

    How do you guys handle impatient users submitting the same form more than once, you know the "click, hmm nothing is happening, better click again, and again......"

    For us, we *know* that every form submission that does something will happen within a flow, so we could define a filter which simply checks for a flow *artifact* and refuses submissions with the same artifact within x number of seconds. What would that flow artifact be? The flow id, the execution id etc.

    If this is the way to go, any pointers on helper code to retrieve flow information from a HttpServletRequest?

    Ta.

  2. #2
    Join Date
    Aug 2004
    Location
    Melbourne, FL
    Posts
    2,794

    Default

    The first thing we do is ensure a request into a FlowExecution (conversation) is synchronized. So it's impossible for one request into the same conversation to be accepted until the previous one completes.

    The next thing we do is provide a TransactionSynchronizer abstraction, allowing you to demarcate a logical transaction for the conversation. So you could "begin a transaction" after the first request and then reject future requests unless they come in for the same transaction. The default TS strategy uses a transaction token, managed in flowScope. Another strategy uses a token managed in an external data store.

    Item List demonstrates the use of the TS interface.

    Is there anything else that makes sense to do?

    Keith
    Keith Donald
    Core Spring Development Team

  3. #3
    Join Date
    Aug 2004
    Posts
    1,905

    Default

    The TS token sounds like a nice solution.

    I will check out the ItemList examples.

    Thanks Keith.

  4. #4
    Join Date
    Aug 2004
    Posts
    1,905

    Default

    Keith, just a thought; how do you synchronise on the flowExecution? Surely each request will instantiate a new instance of the FlowExecution, even if both instances represent the same flowExecution.

  5. #5
    Join Date
    Sep 2004
    Location
    Leuven, Belgium
    Posts
    1,853

    Default

    Unless you're using a continuations based flow execution storage strategy, there is only one FlowExecution object per ongoing flow execution. The start() and signalEvent() methods of the flow execution are synchronized (check the source code for FlowExecutionImpl). So that basically implies that the flow execution can only process one event (request) at a time.


    Erwin

  6. #6
    Join Date
    Aug 2004
    Posts
    1,905

    Default

    Thanks Erwin,

    I am using ClientContinuationFlowExecutionStorage, does that make a difference? This is why I asked the original question, because surely there can now be two instances of a FlowExecution representing the same FlowExecution?

    Also, just reread the "is it right for you" doc, and read:

    As explained in Use continuations to develop complex Web applications, continuations can be used to elegantly handle browser back button use, refreshes and even multiple windows in web applications. Spring Web Flow offers several continuations based flow execution storage strategies, supporting storage of the continuations on either client side or server side. However, before using a continuations based storage strategy in your applications, you should consider the following:

    * The default TransactionSynchronizer implementation that comes with Spring Web Flow to support application transactions uses a synchronizer token stored in the flow execution. This implies that there needs to be a unique flow execution for each running application transaction. As a result you cannot have application transactions when using continuations with the default TransactionSynchronizer: FlowScopeTokenTransactionSynchronizer. Instead, you'll have to configure the flow execution manager to use another transaction synchronizer, like the HttpSessionTokenTransactionSynchronizer, if you want to combine use of a continuations based flow storage strategy with application transactions.
    Unfortunately, we cannot use session at all, so does this mean we are a bit cannot use the TS?

  7. #7
    Join Date
    Sep 2004
    Location
    Leuven, Belgium
    Posts
    1,853

    Default

    I am using ClientContinuationFlowExecutionStorage, does that make a difference? This is why I asked the original question, because surely there can now be two instances of a FlowExecution representing the same FlowExecution?
    With ClientContinuationFlowExecutionStorage you can indeed have multiple FlowExecution objects representing the same 'logical' flow execution.

    Unfortunately, we cannot use session at all, so does this mean we are a bit cannot use the TS?
    You can't use HttpSessionTokenTransactionSynchronizer since that requires an HTTP session. However, you could implement a custom TransactionSynchronizer that works for your particular case, e.g. storing the token in a database. Check the source code of HttpSessionTokenTransactionSynchronizer for an idea of how it works.

    Erwin

  8. #8
    Join Date
    Aug 2004
    Posts
    1,905

    Default

    Thanks Erwin.

  9. #9
    Join Date
    Jan 2006
    Posts
    28

    Default

    Hello all,

    could someone tell me if the double click on form submit has been handled natively in Spring MVC ? If yes, what kind of implementation has been set up (token like in SWF)?

    I can found nothing about this on the documentation, the forum or google.

  10. #10
    Join Date
    Nov 2005
    Posts
    24

    Default

    Keith,
    I had understood that the problem has been resolved in RC1 with redirect.
    In itemlist example in PR5:
    Code:
       <action-state id="addItem">
    		<action bean="addItemAction"/>
    		<transition on="*" to="displayItemlist"/>
    	</action-state>
    The successive request to first generate an error of transaction and come however mapping on the view without to execute the business logic.
    This does not work in more complex cases like:
    Code:
                 <action-state id="addItem">
    		<action bean="addItemAction"/>
    		<transition on="success" to="displayItemlist"/>
                               <transition on="error" to="displayError"/>
                               <transition on="txError" to="?"/>
    	</action-state>
    Where it is not possible to establish the result of the first request.
    I believed that in RC1 (itemlist) the trancaction it has been replaced with redirect:

    Code:
         <bean id="flowExecutor" class="org.springframework.webflow.executor.FlowExecutorImpl">
    		<constructor-arg ref="flowRegistry"/>
    		<property name="alwaysRedirectOnPause" value="true"/>
    	</bean>
    The requests come refused (redirect) until do not arrive one coming from from the last view that restores the flow in active state

    I pray you to correct itself where mistake
    Last edited by wcollazzo; Mar 9th, 2006 at 02:38 AM.

Similar Threads

  1. Replies: 4
    Last Post: Sep 1st, 2010, 01:38 AM
  2. Replies: 3
    Last Post: Jun 8th, 2010, 03:27 AM
  3. need form chain solution
    By mrliang in forum Web Flow
    Replies: 1
    Last Post: Sep 1st, 2005, 09:39 AM
  4. Replies: 3
    Last Post: Jan 26th, 2005, 04:18 AM
  5. Replies: 5
    Last Post: Dec 16th, 2004, 03:19 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •