Uploaded image for project: 'Struts 2'
  1. Struts 2
  2. WW-1831

Common use case for stranded messages in MessageStoreInterceptor

    XMLWordPrintableJSON

Details

    • Improvement
    • Status: Closed
    • Major
    • Resolution: Workaround
    • 2.0.6, 2.0.7, 2.0.8, 2.0.9
    • None
    • Core Interceptors
    • None

    Description

      I have what I think would be a pretty common use case for the MessageStoreInterceptor where, under some circumstances, messages could be left in the session, taking up memory unncessarily.

      The sample use case is that when someone submits an email change, on success I want to redirect them back to their home action, passing any messages (i.e. "Your email has been successfully changed") along for display. I used to do this with action chaining which worked but was sub-optimal since the user would end up back at their home page with an url like "updateEmail.action" rather than "home.action".

      MessageStoreInterceptor seems like the right solution for this case as now I can have the updateEmail store the message, redirect to the home page, and then have home page retrieve it:

      <action name="home"
      class="com.mycompany.action.HomeAction">
      <result>home.ftl</result>
      <interceptor-ref name="store">
      <param name="operationMode">RETRIEVE</param>
      </interceptor-ref>
      <interceptor-ref name="basicStack"/>
      </action>

      <action name="updateEmail"
      class="com.mycompany.action.ChangeEmailAction" method="updateEmail">
      <result type="redirect-action">
      <param name="actionName">home</param>
      </result>
      <result name="input">editEmail.ftl</result>
      <interceptor-ref name="store">
      <param name="operationMode">STORE</param>
      </interceptor-ref>
      <interceptor-ref name="validationStack"/>
      </action>

      The problem is the case when the result of updateEmail is "input" rather than "success". In this case, I just redisplay the change email form, but any validation errors will have been stored in the session. If the user then navigates away or closes the browser, these messages will be stranded in the session.

      I think there is a pretty simple fix for this:

      In MessageStoreInterceptor.before(), simply move the lines:

      session.remove(actionErrorsSessionKey);
      session.remove(actionMessagesSessionKey);
      session.remove(fieldErrorsSessionKey);

      out of the nested ifs so that they are always the last operations in the method.

      This will handle any case other than a redirect/chain to an action that doesn't have the interceptor at all (which can't be helped).

      Another option to this is to explictly support an additional parameter for the Interceptor like "clearStoredMessages" which defaults to false, but if true always calls the session.remove()s at the end of the before().

      Attachments

        Activity

          People

            jholmes James Holmes
            perfnorm Jasper Rosenberg
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: