tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Raiden <rai...@wonko.inow.com>
Subject How to synchronize based on session? (Prevent multiple submissions of forms)
Date Tue, 01 Jul 2003 18:18:49 GMT
Hello,

We are trying to prevent the "multiple submission of a form problem",
that can result when a user double-clicks the submit button.  We have a
process in place, but we have been unable to get the session based
synchronization to work correctly.

Our order page submits to a "meta-refresh" page that checks to see the
current status of the order processing each time it loads.  If there is
an error, it sends the user back to the order page.  If the order was
successful, the user is sent to the success page.  If the order is still
processing, it refreshes in 5 seconds (and meanwhile, the user has a
pretty 5 second progress bar to watch).  However, The relevant snippet of
code is below:

String nextUrl = null;
synchronized (session) {
  BigDecimal status =
    (BigDecimal)session.getAttribute(SiteProps.PROCESS_STATUS);

  if (status != null) {
    System.out.println("  Processing has already begun.  Checking
status.");

    if (status.equals(SiteProps.PROCESS_SUCCESS)) {
      System.out.println("  We already know it was approved.  Just showing
them the success page.");
      nextUrl = "/success.jsp";
      response.sendRedirect(response.encodeRedirectUrl(nextUrl));
      return;  // will remove status object on next page
    } else if (status.equals(SiteProps.PROCESS_ERROR)) {
      System.out.println("  We know the credit card charge failed.  Send
them back to the order form.");
      nextUrl = "/order.jsp";
      response.sendRedirect(response.encodeRedirectUrl(nextUrl));
      return;  // will remove status object on next page
    } else if (status.equals(SiteProps.PROCESS_UNKNOWN)) {
      System.out.println("  Still processing.  Not sure what the result
will be.  This page will refresh in 5 seconds.");
      nextUrl = "/order_check.jsp"; // refresh back to this same page
    }
  } else {
    // we don't have any record of a previous attempt to process
    System.out.println("  First time trying to process order page.
Starting processing, scheduling a refresh.");
    session.setAttribute(SiteProps.PROCESS_STATUS,
      SiteProps.PROCESS_UNKNOWN);
  }
  %>
  <html>
    <!-- progress bar animated gif html code here -->
  </html>
  <%
  if (nextUrl == null) {
    // first time to page

    // order processing code here
  }
}

The problem is, that there isn't any real synchronization here.  This is
because the "session" object is a different object each time this page
loads.  In fact, printing out the "session" object each time the page
loads results in:

org.apache.catalina.session.StandardSessionFacade@24ea85
org.apache.catalina.session.StandardSessionFacade@10275fa
org.apache.catalina.session.StandardSessionFacade@18706f6
org.apache.catalina.session.StandardSessionFacade@f1f34a
org.apache.catalina.session.StandardSessionFacade@fb6763

Since the session object keeps changing, what is the proper way to
synchronize based on the user's session, to make this anti-double-process
code work properly?

This middle page with the progress bar helps to remove most of our
double-click problems, but occassionally a user is able to get multiple
copies of this "progress page" opened, and then if the timing is right,
they both enter that snippet of code above at the same time, both think
it's the first time this page is being processed, and both run the order
processing code.

Thank you,
Raiden


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


Mime
View raw message