Announcement Announcement Module
Collapse
No announcement yet.
How to preserve messages across a top-level flow redirect Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • How to preserve messages across a top-level flow redirect

    I recently ran into a rather common issue with using SWF: messages are not preserved across a top-level flow redirect. I didn't find any good solutions here (or was I just not looking hard enough ), so I came up with something which solves the problem, and thought I'd share it with anyone interested.

    MessagePreserver is a FlowExecutionListener overriding the sessionEnding() and sessionStarting() methods. It's looking for an attribute in the end-state called PRESERVE_MESSAGES. If it finds it, it saves the message snapshot to session scope under PRESERVED_FLOW_MESSAGES. In sessionStarting(), if it finds the snapshot in session scope, it restores the messages.

    To use this, you'll need to add the bean to your webflow config file and add it as a flow execution listener. Whenever you need to preserve across a redirect, add the PRESERVE_MESSAGES attribute to the end-state. Here's the code:

    Code:
    // Use your own package!
    
    import java.io.Serializable;
    
    import org.springframework.binding.message.DefaultMessageContext;
    import org.springframework.webflow.core.collection.MutableAttributeMap;
    import org.springframework.webflow.execution.FlowExecutionListenerAdapter;
    import org.springframework.webflow.execution.FlowSession;
    import org.springframework.webflow.execution.RequestContext;
    
    public class MessagePreserver extends FlowExecutionListenerAdapter  {
      public static final String PRESERVE_MESSAGES = "PRESERVE_MESSAGES";
      private static final String PRESERVED_FLOW_MESSAGES = "PRESERVED_FLOW_MESSAGES";
      
    
      public void sessionStarting(RequestContext requestContext, 
          FlowSession flowSession, MutableAttributeMap attributeMap) {
        Serializable preservedMessages = (Serializable) 
            requestContext.getExternalContext().getSessionMap().get(PRESERVED_FLOW_MESSAGES);
            
        if (preservedMessages != null) {
          DefaultMessageContext currentMessageContext = 
              (DefaultMessageContext) requestContext.getMessageContext();
          currentMessageContext.restoreMessages(preservedMessages);
          requestContext.getExternalContext().getSessionMap().remove(PRESERVED_FLOW_MESSAGES);
        }
      }
    
      public void sessionEnding(RequestContext requestContext, 
          FlowSession flowSession, String string, MutableAttributeMap attributeMap) {
        
        if (requestContext.getCurrentState().getAttributes().contains(PRESERVE_MESSAGES)) {
          Serializable messageSnapshot = 
              ((DefaultMessageContext) requestContext.getMessageContext()).createMessagesMemento();
        
          requestContext.getExternalContext().getSessionMap().
              put(PRESERVED_FLOW_MESSAGES, messageSnapshot);
        }
      }
    }
Working...
X