1 2 3 4 Previous Next 47 Replies Latest reply on Jun 25, 2010 2:31 PM by PhHein Go to original post
      • 45. Re: JSF How to prevent double click ?
        843844
        1.1_02 contains a lot of bugfixes opposed to the first 1.1 release, which is relatively old. Older than this topic.
        • 46. Re: JSF How to prevent double click ?
          843844
          Hello,

          i have tested most of the suggested solutions. The client side solutions with java script don't work (very well) with faces (myfaces 1.2 in geronimo application server 2.1.4). Reason is, the button.disable method changes the faces internal event processing. Such buttons don't fire a reasonable event. Other solutions only work for IE. Hiding of the button works fine, but is a problem if there are hidden buttons in the form which take the same faces action. These buttons are i.e. included to react on enter pressed (if the visible button is not the first one in the form).

          This means, only a server side solution has the chance to work fine under all circumstances. This is my implementation of the suggested Solution of BasheerShaik. The only difference to the proposal is, the reaction on the second submit of the form. This solution redirects to a global warning page "dont hit your button twice"!! The advantage of this behaviour is, it's easier to implement, and it also works fine if the user submits pages of the browser history.

          This is the solution:
          1.) create a method getUniqueId in a controler base class.

          public String getHiddenID() {
                    long ldatum = System.currentTimeMillis();
                    return new Long(ldatum).toString();
          }

          2.) in every page which should be protected against double submit include the following control:

               <h:inputText
                    id="hiddenFormID"
                    styleClass="hidden"
                    value="#{myControler.hiddenID}"
               />

          Note: there is no change in the controler necessary.

          3.) write and configure a simple Filter:

          public class DoubleFilter implements Filter {
          public void doFilter(ServletRequest request, ServletResponse response,
               FilterChain chain) throws IOException, ServletException {
                    
               String url = null;
               
               if (request instanceof HttpServletRequest) {
               url = ((HttpServletRequest)request).getRequestURL().toString();
               
               
               HttpServletResponse resp = (HttpServletResponse) response;
               
               SessionContext sc = getSC();

                                   if (isDuplicateSubmitOfForm(sc,request,url)) {
                                        resp.sendRedirect("/myapp/pages/doubelEnter.jsf");
                                        return;
                                   }

               
               // proceed along the chain
               chain.doFilter(request, response);
               }     


               /**
               * Prüft ob die Form mehrfach submittet wurde. Dies ist schon eine
               * jsp Form aus dem pages Bereich
               *
               * @param sc          SessionContext Objekt des Users
               * @param request     der Request
               * @param url          Name der Page
               * @return
               */
               private boolean isDuplicateSubmitOfForm(SessionContext sc,
                         ServletRequest request,String url) {
                    if (url.endsWith(".jsf")) {

                         String vid = request.getParameter("form:hiddenFormID");
                         if (vid != null && vid.length() > 0) {
                              if (sc.addFormId(vid)) {
                                   return false;
                              }
                              else {
                                   return true;
                              }
                         }
                    }
                    else {
                         //System.out.pxrintln(" --> false");
                    }
                    return false;
               }

          }

          3.) An object of the class SessionContext is saved in the users session. This class implements a buffer of the hiddenFormID's. Each time a request comes in and passes the DoubleFilter the unique id is addes to the buffer. However this is only done if the id is not in the buffer (sc.AddFormId returns true).

          public class SessionContext {

          List<String>     facesIDList = new ArrayList<String>();

          /**
               * Only add the new form id if it is not in the list
               *
               * @param vid form id to add
          *
               * @return true if the id was not in the list and was added
               */
               public synchronized boolean addFormId(String vid) {
                    if (!this.facesIDList.contains(vid)) {
          // dont let the list grow too much
                         if (this.facesIDList.size() > 200) {
                              this.facesIDList.remove(0);
                         }
                         this.facesIDList.add(vid);
                         return true;
                    }          
                    return false;
               }

          }

          4.) configure the filter in web.xml

               <filter>
                    <filter-name>MyDoubleFilter</filter-name>
                    <filter-class>my.DoubleFilter</filter-class>
               </filter>

               <!-- now map this filter to a URL-pattern -->
               <filter-mapping>
                    <filter-name>MyDoubleFilter</filter-name>
                    <url-pattern>/*</url-pattern>
               </filter-mapping>     


          This works fine and is easy to use. Only the jsf hidden Field Tag must be included into the jsp page.
          • 47. Re: JSF How to prevent double click ?
            PhHein
            Ralf, thanks for the contribution, but please don't post in threads that are long dead and don't hijack other threads. When you have a question, start your own topic. Feel free to provide a link to an old post that may be relevant to your problem.

            And in future, use code tags when posting code.

            I'm locking this thread now.
            1 2 3 4 Previous Next