Announcement Announcement Module
Collapse
No announcement yet.
Solution to double form submit... Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • 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
    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

    Comment


    • #3
      The TS token sounds like a nice solution.

      I will check out the ItemList examples.

      Thanks Keith.

      Comment


      • #4
        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.

        Comment


        • #5
          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

          Comment


          • #6
            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?

            Comment


            • #7
              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

              Comment


              • #8
                Thanks Erwin.

                Comment


                • #9
                  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.

                  Comment


                  • #10
                    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, 03:38 AM.

                    Comment


                    • #11
                      Better solution in new version ?

                      I am reading this post after 5 years. Just wanted to check if there is any better solution or any other example other than List to handle double form submission in spring webflow ?

                      Comment

                      Working...
                      X