Question

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 using the location pattern as in the webflow docs:

   <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:

./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":

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"):

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?

Thanks!

Était-ce utile?

La solution

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:

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:

   <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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top