You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Ralph Johnston <ta...@rjohnston.net> on 2005/08/31 02:05:39 UTC

Preventing multiple form submission within Tapestry

Hi, we're working on a project in which we need to submit a form which then creates  
a record in a database on successful submission.  The problem we have is that if  
someone clicks on the submit button more than once, it creates duplicate records of  
the record that the person is trying to submit.   

We've searched the mailing list archives (as best we can) with no luck.  We know  
there is a way to prevent this using Javascript.  However, not all the people using our  
form are guaranteed to have Javascript enabled.  Therefore, we need a way of  
disabling the button or creating a semaphore of sorts to prevent multiple submissions  
that either create the new record or alter it in a drastic way.  Some ideas we have  
are...   

1) Send back something that will disable the button's submit ability to submit the form  
again. For example, somehow killing TCP connection to that form until the submit is  
done.  

2) Hanging when the submission occurs, like display a white page until it's done so  
that the user doesn't click something else and terminate the submission.  

3) Letting the user do whatever he/she wants with the web page particularly by  
disabling all the other submit buttons but when the original submit listener finishes  
what it's doing, it redirects like we want it to do to the appropriate page no matter  
what page the user is on.  

Any other ideas or even solutions would be appreciated. Thank you.  

Ralph Johnston / Phil Whaley 
The Pathfinder Group, Ltd. 

---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org


RE: Preventing multiple form submission within Tapestry

Posted by Patrick Casey <pa...@adelphia.net>.
	Throw a PageRedirectException and redirect to your confirmation
page.

	---- Pat

> -----Original Message-----
> From: Ralph Johnston [mailto:tapestry-users@rjohnston.net]
> Sent: Tuesday, August 30, 2005 8:11 PM
> To: Tapestry users
> Subject: Re: Preventing multiple form submission within Tapestry
> 
> Tom,
> 
> Thanks for the reply.  That is pretty much what we are doing, but how do
> we reject
> the extra submissions?  If we just return from the listener method on
> subsequent
> calls, then the user sees the same page, instead of the confirmation page.
> 
> Thanks!
> 
> > Ralph Johnston wrote:
> > > Hi, we're working on a project in which we need to submit a form which
> then creates
> > > a record in a database on successful submission.  The problem we have
> is that if
> > > someone clicks on the submit button more than once, it creates
> duplicate records of
> > > the record that the person is trying to submit.
> > >
> > > We've searched the mailing list archives (as best we can) with no
> luck.  We know
> > > there is a way to prevent this using Javascript.  However, not all the
> people using our
> > > form are guaranteed to have Javascript enabled.  Therefore, we need a
> way of
> > > disabling the button or creating a semaphore of sorts to prevent
> multiple submissions
> > > that either create the new record or alter it in a drastic way.
> >
> > Why not put a hidden field in the form with a serial number, record the
> > most recent number received for each session, and don't accept form
> > submissions with a number equal or less than the last received?
> >
> > Tom
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
> > For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
> >
> >
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tapestry-user-help@jakarta.apache.org




---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org


Re: Preventing multiple form submission within Tapestry

Posted by Ralph Johnston <ta...@rjohnston.net>.
Tom,

Thanks for the reply.  That is pretty much what we are doing, but how do we reject 
the extra submissions?  If we just return from the listener method on subsequent 
calls, then the user sees the same page, instead of the confirmation page.

Thanks!

> Ralph Johnston wrote:
> > Hi, we're working on a project in which we need to submit a form which then creates  
> > a record in a database on successful submission.  The problem we have is that if  
> > someone clicks on the submit button more than once, it creates duplicate records of  
> > the record that the person is trying to submit.   
> > 
> > We've searched the mailing list archives (as best we can) with no luck.  We know  
> > there is a way to prevent this using Javascript.  However, not all the people using our  
> > form are guaranteed to have Javascript enabled.  Therefore, we need a way of  
> > disabling the button or creating a semaphore of sorts to prevent multiple submissions  
> > that either create the new record or alter it in a drastic way.
> 
> Why not put a hidden field in the form with a serial number, record the 
> most recent number received for each session, and don't accept form 
> submissions with a number equal or less than the last received?
> 
> Tom
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
> 
> 



---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org


Re: Preventing multiple form submission within Tapestry

Posted by Richard Kirby <rb...@capdm.com>.
Ralph Johnston wrote:

>We're trying to prevent redirecting to a page that we don't want the user to go to.  
>Granted, they might learn after they get the exception page a couple of times and 
>stop doing multiple submissions, that just isn't a very user friendly way of handling 
>this issue.
>
>What we need to do is find a way to stave off or queue up other page 
>renders (and ignore them) that might follow the initial call of one of the listener 
>methods we're trying to prevent multiple submissions of.  The synchronization 
>solution seems to be the best bet but will this prevent a rerender of the page if other 
>multiple submissions, which would we would return from, occur?  Flow synchronizer 
>looks to be really good but I like stated, redirecting to an exception page generally is 
>bad user friendly design.
>
>Thanks!
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
>For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
>
>  
>
Hi,

You appear to have a little confusion as to how the web works. If the 
user clicks submit a second time, before the first submit has returned, 
the browser will close its end of the connection to the server for the 
1st submit, and open a new connection. However the server will not know 
this and will merrily carry on processing the first submit request, and 
also start on the second submit request. When the server finally 
finishes processing the first submit request, it will try to write the 
result (the real result that you want) back down a closed connection, 
and therefore loses it. The second request when finished will be the 
actual result returned back to the browser, since its connection is the 
one that is open. Note that the second request could theoretically 
finish before the first request!

So, what you could do to protect against this accidental double submit, 
is separate the processing of the request from the returning of the 
resulting page. Then by using the unique token in the form pattern, you 
can detect a double submit. A rough flow would be:

1. Page with form is requested. Generate a unique token hidden on the form.
2. Form listener request comes in with unique token.
3. Form Listener, synchronizing on some shared object, such as your 
Visit object, immediately checks to see if the unique token has already 
been processed.
    If so, it looks up the result (waiting for the result - using a 
semaphore perhaps) of that processing and renders the response.
    If not, it notes that the unique token is being processed, and then 
starts processing (such as adding the data from the form into the database).
    When the processing has finished, it notes that the unique token has 
finished, and stores any required result. It then renders the response.

On a multiple submit scenario - all the submits will send the same 
unique token. The very first one will cause the form processing to 
happen, and all the rest will wait until the processing has finished 
before attempting to send back the resulting response. Only the last 
submit will actually send a response that the browser will see, since 
all the previous connections will be closed by the browser!

Hope this helps

Richard




---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org


Re: Preventing multiple form submission within Tapestry

Posted by Ralph Johnston <ta...@rjohnston.net>.
We're trying to prevent redirecting to a page that we don't want the user to go to.  
Granted, they might learn after they get the exception page a couple of times and 
stop doing multiple submissions, that just isn't a very user friendly way of handling 
this issue.

What we need to do is find a way to stave off or queue up other page 
renders (and ignore them) that might follow the initial call of one of the listener 
methods we're trying to prevent multiple submissions of.  The synchronization 
solution seems to be the best bet but will this prevent a rerender of the page if other 
multiple submissions, which would we would return from, occur?  Flow synchronizer 
looks to be really good but I like stated, redirecting to an exception page generally is 
bad user friendly design.

Thanks!

---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org


Re: Preventing multiple form submission within Tapestry

Posted by Tom Davies <to...@atlassian.com>.
Ralph Johnston wrote:
> Hi, we're working on a project in which we need to submit a form which then creates  
> a record in a database on successful submission.  The problem we have is that if  
> someone clicks on the submit button more than once, it creates duplicate records of  
> the record that the person is trying to submit.   
> 
> We've searched the mailing list archives (as best we can) with no luck.  We know  
> there is a way to prevent this using Javascript.  However, not all the people using our  
> form are guaranteed to have Javascript enabled.  Therefore, we need a way of  
> disabling the button or creating a semaphore of sorts to prevent multiple submissions  
> that either create the new record or alter it in a drastic way.

Why not put a hidden field in the form with a serial number, record the 
most recent number received for each session, and don't accept form 
submissions with a number equal or less than the last received?

Tom

---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org


Re: Preventing multiple form submission within Tapestry

Posted by Nick Westgate <ni...@key-planning.co.jp>.
Hi.

Like Pat says, you need to synchronize/serialize your requests somehow.
I use a modified RequestControlFilter, originally from:
http://www.onjava.com/pub/a/onjava/2004/03/24/loadcontrol.html?page=1

You also need to prevent multiple submissions server-side.
I use a variation on the FlowSynchronizer from:
http://www.junlu.com/msg/85270.html

It should be easy to modify these to suit your requirements.

For instance, I didn't like the exceptions in FlowSynchronizer,
so I changed it to use a boolean that I can check in my form
listeners when I want to avoid multiple form submissions.

Cheers,
Nick.


Patrick Casey wrote:
> 	This ought to work:
> 
> 	Step 1: Synchronize your servlet.doService() on the HttpSession so
> that two user requests will never run in parallel.
> 	Step 2: Add a hidden, monotonically increasing (like a static
> incrementer) hidden value to the form in question.
> 	Step 3: Add a LinkedHashMap to your Visit object called
> "LastFiveSubmits". Set its removeOldest() to remove if the map size > 5.
> 	Step 4: When you get a "submit" request, check and see if you're
> already handled a submit for this form in, say, the last 5 interactions. If
> not, handle the submit, and stuff it's submission ID into the linkedhashmap
> (from step 3).
> 
> 	That should do the trick.
> 
> 	Of course, using javascript to disable the submit button is much
> easier, but if you can't, you can't.
> 
> 	--- Pat
> 
> 
> 
>>-----Original Message-----
>>From: Ralph Johnston [mailto:tapestry-users@rjohnston.net]
>>Sent: Tuesday, August 30, 2005 5:06 PM
>>To: Tapestry users
>>Subject: Preventing multiple form submission within Tapestry
>>
>>Hi, we're working on a project in which we need to submit a form which
>>then creates
>>a record in a database on successful submission.  The problem we have is
>>that if
>>someone clicks on the submit button more than once, it creates duplicate
>>records of
>>the record that the person is trying to submit.
>>
>>We've searched the mailing list archives (as best we can) with no luck.
>>We know
>>there is a way to prevent this using Javascript.  However, not all the
>>people using our
>>form are guaranteed to have Javascript enabled.  Therefore, we need a way
>>of
>>disabling the button or creating a semaphore of sorts to prevent multiple
>>submissions
>>that either create the new record or alter it in a drastic way.  Some
>>ideas we have
>>are...
>>
>>1) Send back something that will disable the button's submit ability to
>>submit the form
>>again. For example, somehow killing TCP connection to that form until the
>>submit is
>>done.
>>
>>2) Hanging when the submission occurs, like display a white page until
>>it's done so
>>that the user doesn't click something else and terminate the submission.
>>
>>3) Letting the user do whatever he/she wants with the web page
>>particularly by
>>disabling all the other submit buttons but when the original submit
>>listener finishes
>>what it's doing, it redirects like we want it to do to the appropriate
>>page no matter
>>what page the user is on.
>>
>>Any other ideas or even solutions would be appreciated. Thank you.
>>
>>Ralph Johnston / Phil Whaley
>>The Pathfinder Group, Ltd.
>>
>>---------------------------------------------------------------------
>>To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
>>For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
> 
> 
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
> 
> 

---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org


RE: Preventing multiple form submission within Tapestry

Posted by Patrick Casey <pa...@adelphia.net>.
	This ought to work:

	Step 1: Synchronize your servlet.doService() on the HttpSession so
that two user requests will never run in parallel.
	Step 2: Add a hidden, monotonically increasing (like a static
incrementer) hidden value to the form in question.
	Step 3: Add a LinkedHashMap to your Visit object called
"LastFiveSubmits". Set its removeOldest() to remove if the map size > 5.
	Step 4: When you get a "submit" request, check and see if you're
already handled a submit for this form in, say, the last 5 interactions. If
not, handle the submit, and stuff it's submission ID into the linkedhashmap
(from step 3).

	That should do the trick.

	Of course, using javascript to disable the submit button is much
easier, but if you can't, you can't.

	--- Pat


> -----Original Message-----
> From: Ralph Johnston [mailto:tapestry-users@rjohnston.net]
> Sent: Tuesday, August 30, 2005 5:06 PM
> To: Tapestry users
> Subject: Preventing multiple form submission within Tapestry
> 
> Hi, we're working on a project in which we need to submit a form which
> then creates
> a record in a database on successful submission.  The problem we have is
> that if
> someone clicks on the submit button more than once, it creates duplicate
> records of
> the record that the person is trying to submit.
> 
> We've searched the mailing list archives (as best we can) with no luck.
> We know
> there is a way to prevent this using Javascript.  However, not all the
> people using our
> form are guaranteed to have Javascript enabled.  Therefore, we need a way
> of
> disabling the button or creating a semaphore of sorts to prevent multiple
> submissions
> that either create the new record or alter it in a drastic way.  Some
> ideas we have
> are...
> 
> 1) Send back something that will disable the button's submit ability to
> submit the form
> again. For example, somehow killing TCP connection to that form until the
> submit is
> done.
> 
> 2) Hanging when the submission occurs, like display a white page until
> it's done so
> that the user doesn't click something else and terminate the submission.
> 
> 3) Letting the user do whatever he/she wants with the web page
> particularly by
> disabling all the other submit buttons but when the original submit
> listener finishes
> what it's doing, it redirects like we want it to do to the appropriate
> page no matter
> what page the user is on.
> 
> Any other ideas or even solutions would be appreciated. Thank you.
> 
> Ralph Johnston / Phil Whaley
> The Pathfinder Group, Ltd.
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tapestry-user-help@jakarta.apache.org




---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org