Page 1 of 2 12 LastLast
Results 1 to 10 of 14

Thread: Triggering a SWF 2.0 flow from JSF

  1. #1
    Join Date
    Jun 2007
    Location
    Dublin, Ireland
    Posts
    72

    Default Triggering a SWF 2.0 flow from JSF

    In SWF 1.0 if the action was of the form flowId:myFlow the flow would be executed. I'm having difficulty getting this to work in SWF 2.0.

    My understanding now is that I have to set up a SimpleUrlHandlerMapping and make a request to the URL specified within. I can't get this to work as the navigation rules are not being executed??

  2. #2
    Join Date
    Aug 2004
    Location
    Melbourne, FL
    Posts
    2,794

    Default

    Have you looked at the booking reference example?
    Code:
    	<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    		<property name="mappings">
    			<value>
    				/main=flowController
    				/booking=flowController
    			</value>
    		</property>
    		<property name="defaultHandler">
    			<!-- Selects view names to render based on the request URI: e.g. /main selects "main" -->	
    			<bean class="org.springframework.web.servlet.mvc.UrlFilenameViewController" />
    		</property>
    	</bean>
    /main and /booking are flow URL definitions. You would add further url mappings here, like /foo, /bar, etc... "foo" or "bar" then becomes the flow id...

    Keith
    Keith Donald
    Core Spring Development Team

  3. #3
    Join Date
    Jun 2007
    Location
    Dublin, Ireland
    Posts
    72

    Default

    Hi Keith,
    Thanks for responding.

    I have used the configuration in the guide. If i navigate to the url mapped to the flow controller directly, the flow executes as expected, invokes subflows etc.

    I think it is more that JSF is not navigating to the url that is mapped to the flowController.

    What I did was, invoke a JSF action. Create a JSF navigation rule that redirects to the url mapped to the flow controller. This navigation rule is never invoked and I'm puzzled why. Perhaps this is not the best way to do this and you have a better suggestion?

  4. #4
    Join Date
    Jun 2007
    Location
    Dublin, Ireland
    Posts
    72

    Default

    To give you some more information i have posted the relevant configuration below.

    The JSF action is invoked from a rich faces menu item.

    Code:
    <rich:menuItem value="Price Plan Administration" action="pricePlanList"/>
    faces-navigation.xml
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    
    <faces-config xmlns="http://java.sun.com/xml/ns/javaee"
    		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    		xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd"
    		version="1.2">
    		
        <navigation-rule>
            <from-view-id>*</from-view-id> 
    
            <navigation-case>
                <from-outcome>pricePlanList</from-outcome> 
                <to-view-id>/pricePlanList</to-view-id>
                <redirect/> 
            </navigation-case>
        </navigation-rule>
    </faces-config>
    web.xml
    Code:
    <?xml version="1.0" encoding="ISO-8859-1"?>
    
    <web-app version="2.5"
             xmlns="http://java.sun.com/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    
        <!-- Spring Core Configuration -->
        <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
        
        <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationContext/applicationContext*.xml</param-value>
        </context-param>
        
        <servlet>
            <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value></param-value>
            </init-param>
            <load-on-startup>2</load-on-startup>
        </servlet>
        
        <servlet-mapping>
            <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
            <url-pattern>/spring/*</url-pattern>
        </servlet-mapping>
    
        <servlet>
            <servlet-name>Resources Servlet</servlet-name>
            <servlet-class>org.springframework.js.resource.ResourceServlet</servlet-class>
            <load-on-startup>0</load-on-startup>
        </servlet>
    
        <servlet-mapping>
            <servlet-name>Resources Servlet</servlet-name>
            <url-pattern>/resources/*</url-pattern>
        </servlet-mapping>
    
        <filter>
            <filter-name>openEntityManagerInViewFilter</filter-name>
            <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
        </filter>
    
        <filter-mapping>
            <filter-name>openEntityManagerInViewFilter</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
    
        <!-- Java Server Faces Configuration -->
        <servlet>
            <servlet-name>Faces Servlet</servlet-name>
            <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
            <load-on-startup>1</load-on-startup>
        </servlet>
        
        <servlet-mapping>
            <servlet-name>Faces Servlet</servlet-name>
            <url-pattern>/faces/*</url-pattern>
        </servlet-mapping>
    
        <context-param> 
            <param-name>javax.faces.CONFIG_FILES</param-name> 
            <param-value>/WEB-INF/faces-application.xml,/WEB-INF/faces-beans.xml,/WEB-INF/faces-navigation.xml</param-value> 
        </context-param> 
    
        <context-param>
            <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
            <param-value>.xhtml</param-value>
        </context-param>
         
        <context-param>
            <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
            <param-value>server</param-value>
        </context-param>
        
        <!-- Rich Faces Configuration -->
        <context-param>
            <param-name>org.richfaces.SKIN</param-name>
            <param-value>blueSky</param-value>
        </context-param>
        
        <filter>
            <filter-name>richfaces</filter-name>
            <filter-class>org.ajax4jsf.Filter</filter-class>
        </filter>
    
        <filter-mapping>
            <filter-name>richfaces</filter-name>
            <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
            <dispatcher>REQUEST</dispatcher>
            <dispatcher>FORWARD</dispatcher>
            <dispatcher>INCLUDE</dispatcher>
        </filter-mapping>
        
        <!-- Facelet Configuration -->
        <session-config>
            <session-timeout>10</session-timeout>
        </session-config>
    
        <welcome-file-list>
            <welcome-file>/indexProxy.jsp</welcome-file>
        </welcome-file-list>
    </web-app>
    applicationContext-webflow.xml
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:webflow="http://www.springframework.org/schema/webflow-config"
        xmlns:faces="http://www.springframework.org/schema/faces"
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
            http://www.springframework.org/schema/webflow-config
            http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.0.xsd
            http://www.springframework.org/schema/faces
            http://www.springframework.org/schema/faces/spring-faces-2.0.xsd">
    
    	<webflow:flow-registry id="flowRegistry" flow-builder-services="facesFlowBuilderServices">
    		<webflow:flow-location-pattern value="classpath:/applicationContext/webflow/**/*.xml" />
    	</webflow:flow-registry>
    
    	<webflow:flow-executor id="flowExecutor"/>
    	
    	<!-- Configures the Spring Web Flow JSF integration -->
        <faces:flow-builder-services id="facesFlowBuilderServices"/>
    </beans>
    applicationContext-web.xml
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="
               http://www.springframework.org/schema/beans
               http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
    
        <!-- Handles requests mapped to the Spring Web Flow system -->
        <bean id="flowController" class="org.springframework.webflow.mvc.servlet.FlowController">
            <property name="ajaxHandler">
                <bean class="org.springframework.faces.richfaces.RichFacesAjaxHandler"/>
            </property>
            <property name="flowExecutor" ref="flowExecutor"/>
        </bean>
    
        <!-- Maps request URIs to controllers -->           
        <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
            <property name="mappings">
                <value>
                    /pricePlanList=flowController
                </value>
            </property>
            <property name="defaultHandler">
                <!-- Selects view names to render based on the request URI: e.g. /main selects "main" -->   
                <bean class="org.springframework.web.servlet.mvc.UrlFilenameViewController" />
            </property>
        </bean>
        
        <!-- Maps logical view names to Facelet templates (e.g. 'search' to '/WEB-INF/search.xhtml' -->
        <bean id="faceletsViewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
            <property name="viewClass" value="org.springframework.faces.mvc.JsfView"/>
            <property name="prefix" value="/" />
            <property name="suffix" value=".xhtml" />
        </bean>
    </beans>

  5. #5
    Join Date
    Jun 2008
    Location
    Madrid
    Posts
    12

    Default

    Hi everyone!

    I'm working on an existing JSF application and I'd like to use Web Flow 2.

    Since we're talking about an existing application, I just can't ignore or migrate all my JSF navigation-rules, though discarding the spring-centric setup for SWF.

    So I went to the jsf-booking example... and I found it's just for using Spring as a managed-bean provider!!! So there's no jsf-centric example using webflow?

  6. #6
    Join Date
    Jun 2007
    Location
    Dublin, Ireland
    Posts
    72

    Post One Option

    I have found a solution that works for me however contrived. It would be nice to hear the feedback from the spring team as to how this could be better achieved.

    The majority of the configuration is as posted on Tuesday at 10:38 AM.

    Requests are initially processed by the faces servlet. Within the JSF application I have a UICommand element as below. Clicking this invokes the action listener which in turn redirects the spring dispatcher servlet. The flow executes. To return to the faces servlet on completion of the flow i change toe flow end-state to do an external redirect.

    Code:
    <rich:menuItem value="Price Plan Administration">
      <f:actionListener type="com.o2.core.faces.listener.FlowRedirectActionListener"/>
      <f:attribute name="flowId" value="pricePlanList"/>
    </rich:menuItem>
    Code:
    public class FlowRedirectActionListener implements ActionListener {
    
    	private static final String ATTRIBUTE_FLOWID = "flowId";
    	
    	public void processAction(ActionEvent event) throws AbortProcessingException {
    		try {
    			String flowId =
    				(String) event.getComponent().getAttributes().get(ATTRIBUTE_FLOWID);
    			
    			FacesContext facesContext = FacesContext.getCurrentInstance();
    			facesContext.getExternalContext().redirect("/fmb-console/spring/" + flowId);
    			facesContext.responseComplete();
    		} catch (IOException exception) {
    			throw new AbortProcessingException(exception);
    		}
    	}
    }
    Code:
    <end-state id="ok" view="externalRedirect:http://localhost:7001/fmb-console/faces/index.xhtml"/>
    Considering the simplicity with which this was achieved with SWF 1.0 i find it hard to believe that there is not an easier way with SWF 2.0. Any feedback??

  7. #7
    Join Date
    Apr 2005
    Location
    San Francisco, CA
    Posts
    1,224

    Default

    Yes, we had gone with the idea that it would be simple enough to just request the URL for the flow directly using techniques such as what you've shown, but your example makes a good case for restoring something similar to the "flowId:" special navigation outcome for these types of mixed-use cases. Open a Jira and we will consider a way to do this.
    Jeremy Grelle

    Staff Engineer, Web Products Team
    SpringSource

  8. #8
    Join Date
    Jun 2007
    Location
    Dublin, Ireland
    Posts
    72

    Default Jira

    Cheers, I'll open the JIRA this evening.

    This was so much simpler in 1.0.5 but then again, the new flow definition and persistence context stuff is a step in the right direction.

    John

  9. #9
    Join Date
    Jun 2007
    Location
    Dublin, Ireland
    Posts
    72

    Default

    JIRA issue added at: http://jira.springframework.org/browse/SWF-768

    If this is impacting on your project please log in and vote for the issue.

  10. #10
    Join Date
    Aug 2004
    Location
    Melbourne, FL
    Posts
    2,794

    Default

    Turner,

    Just reading over this thread again. It seems you are trying to redirect to a new flow from inside your current flow using a JSF command? If this is what you are trying to do, you might want to consider simply doing this as part of standard Web Flow event processing. Specifically, have your action map to a Web Flow event in your current flow's state that triggers a transition to an end-state that performs a flow redirect. See the XSD docs or ref docs for how to do a flow redirect from an end-state.

    HTH

    Keith
    Keith Donald
    Core Spring Development Team

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •