Announcement Announcement Module
Collapse
No announcement yet.
URI mapping to flow ID containing slash ("/") Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • URI mapping to flow ID containing slash ("/")

    We have a requirement to handle login and signup slightly differently within a subsection of our website. We need separate flows for each of the following URIs.

    /login
    /signup
    /subsection/login
    /subsection/signup

    Our flow-registry is configured as in the documentation:

    Code:
       <flow:flow-registry id="flowRegistry" base-path="/WEB-INF/flow" flow-builder-services="flowBuilderServices">
          <flow:flow-location-pattern value="/**/*-flow.xml" />
       </flow:flow-registry>
    And the flow XML files are in the following structure:

    Code:
    ./root/src/main/webapp/WEB-INF/flow
    |-- subsection
    |   |-- login
    |   |   `-- subsection-login-flow.xml
    |   `-- signup
    |       `-- subsection-signup-flow.xml
    |-- login
    |   `-- login-flow.xml
    `-- signup
        `-- signup-flow.xml
    With DEBUG logging enabled, I can see in the logs that four flows are created with the IDs "login", "signup", "subsection/login", and "subsection/signup":

    Code:
    24-Apr 09:21:50,887 DEBUG RMI TCP Connection(2)-127.0.0.1 definition.registry.FlowDefinitionRegistryImpl -  Registering flow definition 'ServletContext resource [/WEB-INF/flow/subsection/login/subsection-login-flow.xml]' under id 'subsection/login'   
    24-Apr 09:21:50,887 DEBUG RMI TCP Connection(2)-127.0.0.1 definition.registry.FlowDefinitionRegistryImpl -  Registering flow definition 'ServletContext resource [/WEB-INF/flow/subsection/signup/subsection-signup-flow.xml]' under id 'subsection/signup'   
    24-Apr 09:21:50,888 DEBUG RMI TCP Connection(2)-127.0.0.1 definition.registry.FlowDefinitionRegistryImpl -  Registering flow definition 'ServletContext resource [/WEB-INF/flow/login/login-flow.xml]' under id 'login'   
    24-Apr 09:21:50,889 DEBUG RMI TCP Connection(2)-127.0.0.1 definition.registry.FlowDefinitionRegistryImpl -  Registering flow definition 'ServletContext resource [/WEB-INF/flow/signup/signup-flow.xml]' under id 'signup'
    When I go to http://mysite.com/login or http://mysite.com/signup, everything works as expected.

    However, when I go to http://mysite.com/subsection/login or http://mysite.com/subsection/signup, the URIs get mapped to "login" (instead of "subsection/login") or "signup" (instead of "subsection/signup"):

    Code:
    24-Apr 09:32:16,917 DEBUG ajp-bio-8009-exec-5 mvc.servlet.FlowHandlerMapping -  Mapping request with URI '/subsection/signup' to flow with id 'signup'
    I traced through this in the debugger, and the DefaultFlowUrlHandler.getFlowId method is returning the flow ID based just on whatever follows the last "/", so for the URI "/subsection/signup", the flow ID returned is simply "signup".

    What am I doing wrong here? Is there any way to force the desired flow mapping? The examples given in the documentation indicate that it's possible to map a flow to an ID containing a slash.

    Thanks!

  • #2
    I figured this out. The documentation for DefaultFlowUrlHandler states:

    Expects URLs to launch flow to be of this pattern:

    http://<host>/[app context path]/[app servlet path]/<flow path>
    So for the URI "/subsection/signup", app context path is empty (for our webapp), app servlet path is "subsection", and flow path is "signup". Hence, this was mapping to the "signup" flowId instead of "subsection/signup".

    I fixed this by subclassing DefaultFlowUrlHandler and overriding the getFlowId method:

    Code:
    public class UriFlowUrlHandler extends DefaultFlowUrlHandler
    {
       @Override
       public String getFlowId(HttpServletRequest request)
       {
          // Strip off leading "/" and any file extension (e.g., ".jsp")
          String uriNoExtension = StringUtils.substringBeforeLast(request.getRequestURI().substring(1), ".");
    
          if (StringUtils.isNotEmpty(uriNoExtension))
             return uriNoExtension;
          else
             return super.getFlowId(request);
       }
    }
    Then I inject this bean into the FlowHandlerMapping in my webflow context:

    Code:
       <bean id="uriFlowUrlHandler" class="com.mycompany.web.spring.UriFlowUrlHandler" />
    
       <bean class="org.springframework.webflow.mvc.servlet.FlowHandlerMapping">
          <property name="flowRegistry" ref="flowRegistry" />
          <property name="alwaysUseFullPath" value="true" />
          <property name="flowUrlHandler" ref="uriFlowUrlHandler" />
       </bean>
    Perhaps there's a better way, but this works.

    Comment

    Working...
    X