Announcement Announcement Module
Collapse
No announcement yet.
Tip: Accessing a flow execution from outside Spring Web Flow Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Tip: Accessing a flow execution from outside Spring Web Flow

    This thread discusses the "Accessing a flow execution from outside Spring Web Flow" tip published on the Ervacon Spring Web Flow Portal.

    Read the tip at

    http://www.ervacon.com/products/swf/tips/tip1.html

  • #2
    The code helped me a lot! Thanks a bunch to the author! The only change I made for my use, was to inject the formController instead of getting the ApplicationContext (which I already had, because I extended AbstractController) and then obtaining the formController via getBean().

    I'm just wondering if such a common requirement (accessing flow data outside a flow) should require so much custom code in my application. A static method provided by SWF would be a really nice improvement for 1.0.1 :-)

    Something like -

    FlowExecution flowExecution = FlowExecutionHolder.getFlowExecution(request, flowExecutionKey);


    Best

    Oliver

    Comment


    • #3
      I'm just wondering if such a common requirement (accessing flow data outside a flow) should require so much custom code in my application. A static method provided by SWF would be a really nice improvement for 1.0.1 :-)
      I have been thinking the same thing.
      I'll discuss this with Keith to see what our policy is going to be.

      Erwin

      Comment


      • #4
        I do something like this to instead of reading the flowScope , modify it... but seems like is not really working.. any ideas?


        if (handler.isFlowExecutionKeyPresent(externalContext )) {
        try {
        ExternalContextHolder.setExternalContext(externalC ontext);
        FlowExecutionKey flowExecutionKey = flowE.parseFlowExecutionKey(handler.extractFlowExe cutionKey(externalContext));
        FlowExecution flowExecution = flowE.getFlowExecution(flowExecutionKey);


        MutableAttributeMap flowScope = flowExecution.getActiveSession().getScope();
        if(flowScope.get("VALUETOMODIFY").toString() != null){
        flowScope.put("VALUETOMODIFY","New Data";
        chain.doFilter(request, response);
        return;

        }
        catch (Exception e) {
        e.printStackTrace();
        }
        finally {
        ExternalContextHolder.setExternalContext(null);
        }
        }

        regards...

        Comment


        • #5
          Modifying a flow execution from outside SWF, and hence outside the flow execution, is not really a supported use-case.
          It's not impossible but it will be quite a bit of custom coding: after getting the flow execution you'll have to save it again using the flow execution repo in use.

          Erwin

          Comment


          • #6
            Similar but with one new product for integration

            Hi people,

            I wondering if anyone had tried integrating the following architecture for their web applications:
            Ext-js - Screen Design and validation
            DWR - Data loading mechanism
            Spring webflow - form handling and screen flow

            Presently, I am trying to integrate these three products together. Really enjoy what Ext-JS has to provide in terms of validation, screen designs and their functionalities.
            However, I am having a problem in displaying the form data pass over by Spring webflow using Ext-Js.

            There are two way of approach which i will wan to explore:

            1. I will like to access the flow execution outside of SWF. However, I will need the request to be pass in using DWR. Hence not very sure of how to go about it therefore i currently trying the 2nd approach which is not working
            2. As Spring Webflow is using JSTL to display the form data on the JSPs, however by using Ext-JS we are using javascript to load the form elements and data.

            Example:
            Spring webflow samples app display the passed over form data like this:
            <input type="text" id="myID" value="<c:out value="{$env.ID}"/>"/>
            Hence, I tried using the following method in ext-js (which did not work):
            var myIDTextField = new Ext.form.TextField({
            id:'myID',
            inputType:'text',
            width:100,
            label:'ID',
            value:'<c:out value="{$env.ID}"/>'
            });

            Hence, I am facing such a problem as describe above over there.
            Hope tat you guys can lend me a hand here....

            thanks so much!!!
            Jessica

            Comment


            • #7
              SWF roolz

              klr8

              thanks for this solution, well i am not an expert in SWF, only i have the enough knowledge to work happy with SWF

              about this
              In some situations it is usefull to get access to a Spring Web Flow flow execution from outside of Spring Web Flow itself.
              maybe the question is silly , but,
              can you share some situations ???

              hi jessica1983

              Ext-js - Screen Design and validation
              DWR - Data loading mechanism
              Spring webflow - form handling and screen flow
              i used to work with the 2 last,but
              However, I am having a problem in displaying the form data pass over by Spring webflow using Ext-Js.
              exactly , what is the problem??
              empty field? or some other message error from the server?

              thanks for advanced

              Comment


              • #8
                Hi there!!! here is my description

                Hi there!!!

                thanks for much for your prompt reply / help.

                - I will like to use DWR to display the form data
                - However, the form data is stored in the flow execution (SWF).

                From how I understand it, DWR is a request-on-demand approach. Therefore, DWR cannot be triggered using SWF flow execution. Hence, after looking through the thread over there - "Accessing a flow execution from outside of Spring Web Flow" i thought that maybe it is possible to trigger DWR from javascript where DWR bean will access the flowexecutionkey / request. The problem is, I am not so sure how to go about it in terms of configuration and getting the flowexecutionkey / request / session. I tried the example given in the thread but it seems like I had to throw in the flowexecutionkey / session / request in order to access the form data in Spring webflow.

                Hence I really need some help here...

                I really like to thank you for your help.

                Many Thanks,
                Jessica

                Comment


                • #9
                  Dear jessica

                  From how I understand it, DWR is a request-on-demand approach.
                  well i only know that thi is a good tool/framework to work with ajax and java with objects

                  Therefore, DWR cannot be triggered using SWF flow execution.
                  well not, DWR use js (some event) to call the server, is ajax simply

                  thought that maybe it is possible to trigger DWR from javascript where DWR bean will access the flowexecutionkey / request.
                  normally if i ise DWR to change my bean, in the next action-state of the flow i must update the object, maybe other approach can be valid too

                  The problem is, I am not so sure how to go about it in terms of configuration and getting the flowexecutionkey / request / session.
                  can you share exactly tha case/problem that you want resolve?

                  regards

                  Comment


                  • #10
                    SWF FormDataAccessor

                    Hi.
                    I want to implement the XT Ajax FormDataAccesor in order to submit a form using xt ajax and actualy handle the data in the SWF. I'm using JspComponent to render the response. Anyway, this implementation needs to extract the command object and the validation errors from the flow execution. How can I do this? I can extend the FormAction and expose the form errors and command object which are protected. Or I can copy/paste retrieval logic from the FormObjectAccessor class. Is there someone that did this and can help me with a simpler/cleaner solution? Thank you.

                    Comment


                    • #11
                      Seems that this works. I post it here maybe someone else will need it.

                      Code:
                      import java.util.Map;
                      
                      import javax.servlet.http.HttpServletRequest;
                      import javax.servlet.http.HttpServletResponse;
                      
                      import org.apache.log4j.Logger;
                      import org.springframework.validation.Errors;
                      import org.springframework.webflow.action.FormObjectAccessor;
                      import org.springframework.webflow.context.ExternalContext;
                      import org.springframework.webflow.context.ExternalContextHolder;
                      import org.springframework.webflow.context.servlet.ServletExternalContext;
                      import org.springframework.webflow.execution.FlowExecution;
                      import org.springframework.webflow.execution.repository.FlowExecutionKey;
                      import org.springframework.webflow.execution.repository.FlowExecutionRepository;
                      import org.springframework.webflow.executor.FlowExecutorImpl;
                      import org.springframework.webflow.executor.mvc.FlowController;
                      import org.springframework.webflow.executor.support.FlowExecutorArgumentHandler;
                      import org.springmodules.xt.ajax.FormDataAccessor;
                      
                      /**
                       * 
                       * @author Elvis Ciocoiu
                       *
                       */
                      public class SWFFormDataAccessor implements FormDataAccessor {
                      	private static final Logger LOG = Logger.getLogger(SWFFormDataAccessor.class);
                      	
                      	public Object getCommandObject(HttpServletRequest request,
                      			HttpServletResponse response, Object handler, Map model) {
                      		
                      		Object command = extract(request, response, (FlowController) handler, new SWFAccessorCallback() {
                      
                      			public Object extract(FlowExecution flowExecution) {
                      				return flowExecution.getActiveSession().getScope().get(FormObjectAccessor.getCurrentFormObjectName());
                      			}
                      			
                      		});
                      		
                      		return command;
                      	}
                      
                      	public Errors getValidationErrors(HttpServletRequest request,
                      			HttpServletResponse response, Object handler, Map model) {
                      		Errors errors = (Errors) extract(request, response, (FlowController) handler, new SWFAccessorCallback() {
                      
                      			public Object extract(FlowExecution flowExecution) {
                      				return (Errors) flowExecution.getActiveSession().getFlashMap().get(
                      						FormObjectAccessor.getCurrentFormErrorsName(), Errors.class);
                      			}
                      			
                      		});
                      		
                      		return errors;
                      	}
                      
                      	private Object extract(HttpServletRequest request,
                      			HttpServletResponse response, FlowController flowControllerflowControllertroller, SWFAccessorCallback callbak) {
                      		FlowExecutionRepository repository = ((FlowExecutorImpl)flowControllerflowControllertroller.getFlowExecutor()).getExecutionRepository();
                      		FlowExecutorArgumentHandler argumentHandler  = flowControllerflowControllertroller.getArgumentHandler();
                      		
                      		ExternalContext externalContext = new ServletExternalContext(request.getSession().getServletContext(), request, response);		
                      		
                      		if (argumentHandler.isFlowExecutionKeyPresent(externalContext)) {
                      			try {
                      				ExternalContextHolder.setExternalContext(externalContext);
                      				FlowExecutionKey flowExecutionKey =
                      					repository.parseFlowExecutionKey(argumentHandler.extractFlowExecutionKey(externalContext));
                      				FlowExecution flowExecution = repository.getFlowExecution(flowExecutionKey);
                      				
                      				return callbak.extract(flowExecution);
                      			}
                      			catch (Exception e) {
                      				e.printStackTrace();
                      			}
                      			finally {
                      				ExternalContextHolder.setExternalContext(null);
                      			}
                      		}
                      		
                      		return null;
                      	}
                      
                      	interface SWFAccessorCallback {
                      		Object extract(FlowExecution flowExecution);
                      	}
                      }

                      Comment


                      • #12
                        Hi, i'm working with SWF on Liferay portal.

                        Each portlet has his own PortletFlowController instance and, AFAIK, his own WebApplicationContext.

                        I would like to create a Servlet in my web app to be able to stream PDF file.

                        But actually i'm not able to access to a flow execution contained by one of my portlets.

                        Any ideas ?

                        Thans

                        Comment


                        • #13
                          Is there a webflow 2 version for this tip ?

                          We are using this for a Spring MVC controller that returns "image/jpeg" content. The bytes of the image are stored on flowscope and so we need to access the flowscope from within our MVC controller.
                          In webflow 1 this worked out just fine and we tried these changes to get it working in webflow 2.0.8:

                          Code:
                          ApplicationContext context = (ApplicationContext)getServletContext().getAttribute(DispatcherServlet.SERVLET_CONTEXT_PREFIX + "x");
                          
                          FlowController controller = (FlowController)context.getBean("flowController");
                          FlowExecutionRepository repository = ((FlowExecutorImpl)controller.getFlowExecutor()).getExecutionRepository();
                          
                          ExternalContext externalContext = new ServletExternalContext(getServletContext(), request, response);
                          ExternalContextHolder.setExternalContext(externalContext);
                          FlowExecutionKey flowExecutionKey = repository.parseFlowExecutionKey(ServletRequestUtils.getRequiredStringParameter(request, "_flowExecutionKey"));
                          
                          FlowExecution flowExecution = repository.getFlowExecution(flowExecutionKey);
                          
                          MutableAttributeMap flowScope = flowExecution.getActiveSession().getScope();
                          However, this does not seem work 100%. Sometimes we get "SnapshotNotFoundException" for some of our images. It isn't really clear and there is no rule as to when this exception occurs.

                          Comment


                          • #14
                            please update this tip as per latest webflow api

                            Comment


                            • #15
                              Flow scope data outside SWF

                              Is there any update on this ?

                              Comment

                              Working...
                              X