Struts 2
  1. Struts 2
  2. WW-3415

Issues with Token session interceptor - Blank page is returned in case of double submission

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 2.0.11.1
    • Fix Version/s: 2.3.20
    • Component/s: Core Interceptors
    • Labels:
      None
    • Flags:
      Important

      Description

      Blank page is returned in case of double submission. I am using struts version - 2.0.11.1

      I have extendend TokenSessionStoreInterceptor class in my code and not changed any functionality. Following is how my class looks like

      public class MyClass extends TokenSessionStoreInterceptor{
      /**

      • Default Serial Version Id
        */
        private static final long serialVersionUID = 1L;

      protected String handleInvalidToken(ActionInvocation invocation) throws Exception {
      ActionContext ac = invocation.getInvocationContext();

      HttpServletRequest request = (HttpServletRequest) ac.get(ServletActionContext.HTTP_REQUEST);
      HttpServletResponse response = (HttpServletResponse) ac.get(ServletActionContext.HTTP_RESPONSE);
      String tokenName = TokenHelper.getTokenName();
      String token = TokenHelper.getToken(tokenName);

      if ((tokenName != null) && (token != null)) {
      Map params = ac.getParameters();
      params.remove(tokenName);
      params.remove(TokenHelper.TOKEN_NAME_FIELD);

      ActionInvocation savedInvocation = InvocationSessionStore.loadInvocation(tokenName, token);

      if (savedInvocation != null) {
      // set the valuestack to the request scope
      ValueStack stack = savedInvocation.getStack();
      Map context = stack.getContext();
      request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, stack);

      ActionContext savedContext = savedInvocation.getInvocationContext();
      savedContext.getContextMap().put(ServletActionContext.HTTP_REQUEST, request);
      savedContext.getContextMap().put(ServletActionContext.HTTP_RESPONSE, response);
      Result result = savedInvocation.getResult();

      if ((result != null) && (savedInvocation.getProxy().getExecuteResult())) {
      synchronized (context)

      { result.execute(savedInvocation); }

      }

      // turn off execution of this invocations result
      invocation.getProxy().setExecuteResult(false);

      return savedInvocation.getResultCode();
      }
      }

      return INVALID_TOKEN_CODE;
      }

      protected String handleValidToken(ActionInvocation invocation) throws Exception

      { // we know the token name and token must be there String key = TokenHelper.getTokenName(); String token = TokenHelper.getToken(key); InvocationSessionStore.storeInvocation(key, token, invocation); return invocation.invoke(); }

      }

      Now, whenever I do a double submission for a functionality like search (which gets loads of data from the database), previously saved invocation does not complete and savedInvocation.getResultCode() returns null (inside handleInvalidToken method). Due to which I receive a blank page.

      Whenever I do a debug(from eclipse) on handleInvalidToken method, savedInvocation.getResultCode() value changes from null to "success" as I wait inside the method for sometime.

      I have also put in savedInvocation.isExecuted() in this handleInvalidToken method and noticed that its value changes from false to true if I wait on the line of code for some time.

        Activity

        Lukasz Lenart made changes -
        Status Open [ 1 ] Closed [ 6 ]
        Assignee Lukasz Lenart [ lukaszlenart ]
        Resolution Fixed [ 1 ]
        Hide
        Lukasz Lenart added a comment -

        I'm closing this as both related issues were solved

        Show
        Lukasz Lenart added a comment - I'm closing this as both related issues were solved
        Hide
        Lukasz Lenart added a comment - - edited

        Maybe it is related to WW-3865 and WW-3895? Can you test with the latest available version?

        Show
        Lukasz Lenart added a comment - - edited Maybe it is related to WW-3865 and WW-3895 ? Can you test with the latest available version?
        Hide
        Simon Bouchard added a comment -

        The bug is also present on 2.3.1.2

        Sachin's fix doesn't work for me. The proposed fix executes a second time the original request - which is most likely not what you want when you're trying to prevent a double submit.

        Show
        Simon Bouchard added a comment - The bug is also present on 2.3.1.2 Sachin's fix doesn't work for me. The proposed fix executes a second time the original request - which is most likely not what you want when you're trying to prevent a double submit.
        Lukasz Lenart made changes -
        Field Original Value New Value
        Fix Version/s 2.3.x [ 12319176 ]
        Hide
        nitin kumar added a comment -

        I get below error.....
        2011-05-11 14:48:27,342 | [] WARN fi.vr.h.web.common.textresource.TextResourceCache - Text resource was not found. Key [Key Locale] was: struts.internal.invalid.tokenFI
        2011-05-11 14:48:27,342 | [] WARN fi.vr.h.web.common.textresource.TextResourceCache - Text resource was not found. Key [Key Locale] was: struts.internal.invalid.token

        Show
        nitin kumar added a comment - I get below error..... 2011-05-11 14:48:27,342 | [] WARN fi.vr.h.web.common.textresource.TextResourceCache - Text resource was not found. Key [Key Locale] was: struts.internal.invalid.tokenFI 2011-05-11 14:48:27,342 | [] WARN fi.vr.h.web.common.textresource.TextResourceCache - Text resource was not found. Key [Key Locale] was: struts.internal.invalid.token
        Hide
        nitin kumar added a comment -

        what is happening is that my invocation.resultcode becomes error in case of double submit.

        i think i need to update my stack.
        can u send me your interceptor stack?

        Show
        nitin kumar added a comment - what is happening is that my invocation.resultcode becomes error in case of double submit. i think i need to update my stack. can u send me your interceptor stack?
        Show
        Lukasz Lenart added a comment - It's a file with diff http://www.dzone.com/links/r/how_to_create_and_apply_a_patch_with_subversion.html
        Hide
        Sachin Tandon added a comment -

        Yes, its working for me without a problem.

        Not sure what do you exactly mean by patch. I have a pasted the code above which I changed to make it work.

        Pardon my ignorance, could you please elaborate on what would you require in the patch?

        Show
        Sachin Tandon added a comment - Yes, its working for me without a problem. Not sure what do you exactly mean by patch. I have a pasted the code above which I changed to make it work. Pardon my ignorance, could you please elaborate on what would you require in the patch?
        Hide
        Lukasz Lenart added a comment -

        Is it working for you without a problem ? Could you prepare a patch and attach it here ?

        Show
        Lukasz Lenart added a comment - Is it working for you without a problem ? Could you prepare a patch and attach it here ?
        Hide
        Sachin Tandon added a comment -

        Yes, I have come up with a work around.

        I have changed the handleInvalidToken method as follows:- Changes made are starts with the comment "//Changes start" and ends with "//Changes end"

        protected String handleInvalidToken(ActionInvocation invocation) throws Exception {
        ActionContext ac = invocation.getInvocationContext();

        HttpServletRequest request = (HttpServletRequest) ac.get(ServletActionContext.HTTP_REQUEST);
        HttpServletResponse response = (HttpServletResponse) ac.get(ServletActionContext.HTTP_RESPONSE);
        String tokenName = TokenHelper.getTokenName();
        String token = TokenHelper.getToken(tokenName);

        if ((tokenName != null) && (token != null)) {
        Map params = ac.getParameters();
        params.remove(tokenName);
        params.remove(TokenHelper.TOKEN_NAME_FIELD);

        ActionInvocation savedInvocation = InvocationSessionStore.loadInvocation(tokenName, token);

        if (savedInvocation != null) {
        // set the valuestack to the request scope
        ValueStack stack = savedInvocation.getStack();
        Map context = stack.getContext();
        request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, stack);

        ActionContext savedContext = savedInvocation.getInvocationContext();
        savedContext.getContextMap().put(ServletActionContext.HTTP_REQUEST, request);
        savedContext.getContextMap().put(ServletActionContext.HTTP_RESPONSE, response);
        Result result = savedInvocation.getResult();

        if ((result != null) && (savedInvocation.getProxy().getExecuteResult())) {
        synchronized (context)

        { result.execute(savedInvocation); }

        }

        // turn off execution of this invocations result
        invocation.getProxy().setExecuteResult(false);

        //Changes start
        //Checks if the saved invocation has been executed as of now. If not it gets executed again.
        if(savedInvocation.isExecuted())

        { return savedInvocation.getResultCode(); }

        else

        { return savedInvocation.invoke(); }

        //Changes end
        }
        }

        Please let know if you stll have questions...

        Show
        Sachin Tandon added a comment - Yes, I have come up with a work around. I have changed the handleInvalidToken method as follows:- Changes made are starts with the comment "//Changes start" and ends with "//Changes end" protected String handleInvalidToken(ActionInvocation invocation) throws Exception { ActionContext ac = invocation.getInvocationContext(); HttpServletRequest request = (HttpServletRequest) ac.get(ServletActionContext.HTTP_REQUEST); HttpServletResponse response = (HttpServletResponse) ac.get(ServletActionContext.HTTP_RESPONSE); String tokenName = TokenHelper.getTokenName(); String token = TokenHelper.getToken(tokenName); if ((tokenName != null) && (token != null)) { Map params = ac.getParameters(); params.remove(tokenName); params.remove(TokenHelper.TOKEN_NAME_FIELD); ActionInvocation savedInvocation = InvocationSessionStore.loadInvocation(tokenName, token); if (savedInvocation != null) { // set the valuestack to the request scope ValueStack stack = savedInvocation.getStack(); Map context = stack.getContext(); request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, stack); ActionContext savedContext = savedInvocation.getInvocationContext(); savedContext.getContextMap().put(ServletActionContext.HTTP_REQUEST, request); savedContext.getContextMap().put(ServletActionContext.HTTP_RESPONSE, response); Result result = savedInvocation.getResult(); if ((result != null) && (savedInvocation.getProxy().getExecuteResult())) { synchronized (context) { result.execute(savedInvocation); } } // turn off execution of this invocations result invocation.getProxy().setExecuteResult(false); //Changes start //Checks if the saved invocation has been executed as of now. If not it gets executed again. if(savedInvocation.isExecuted()) { return savedInvocation.getResultCode(); } else { return savedInvocation.invoke(); } //Changes end } } Please let know if you stll have questions...
        Hide
        nitin.x.kumar@accenture.com added a comment -

        Did you have any workaround to fix this problem.

        Thanks and Regards,
        Nitin Kumar <https://people.accenture.com/personal/MySite/Person.aspx?accountname=nitin.x.kumar>
        Accenture, Gurgaon
        Cell: +91 99991 77763
        --------------------------------------------------------------------------------------------------------
        Happiness keeps u Sweet, Trials keep u Strong, Sorrow keeps u Human, Failure Keeps u Humble, Success keeps u Glowing, But only God Keeps u Going.....
        "A day without laughter is a day wasted"

        Show
        nitin.x.kumar@accenture.com added a comment - Did you have any workaround to fix this problem. Thanks and Regards, Nitin Kumar < https://people.accenture.com/personal/MySite/Person.aspx?accountname=nitin.x.kumar > Accenture, Gurgaon Cell: +91 99991 77763 -------------------------------------------------------------------------------------------------------- Happiness keeps u Sweet, Trials keep u Strong, Sorrow keeps u Human, Failure Keeps u Humble, Success keeps u Glowing, But only God Keeps u Going..... "A day without laughter is a day wasted"
        Sachin Tandon created issue -

          People

          • Assignee:
            Lukasz Lenart
            Reporter:
            Sachin Tandon
          • Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development