You need to try with FlowController and DefaultFlowUrlHandler.
FlowController - It acts as gateway to Web Flow defined control logic and DispatcherServlet.
As per the documentation, in createFlowDefinitionUrl method in DefaultFlowUrlHandler:
The flow definition URL for the given flow id will be built by appending
the flow id to the base app context and servlet paths.
Example - given a request originating at:
http://someHost/someApp/someServlet/nestedPath/foo
and a request for the flow id "nestedPath/bar", the new flow definition URL
would be:
http://someHost/someApp/someServlet/nestedPath/bar
So if request is like: somehost/yourContextPath/yourServletContext/widget/edit/99 and flow id is widget/edit, new flow definition URL would be: somehost/yourContextPath/yourServletContext/widget/edit
Assuming certain configurations as:
The web.xml configuration maps "/widgetinventory/*" requests to the yourServletContext servlet:
<servlet>
<servlet-name>yourServletContext</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>yourServletContext</servlet-name>
<url-pattern>/widgetinventory/*</url-pattern>
</servlet-mapping>
yourServletContext-servlet.xml:
All requests with a servlet path matching "/widgetinventory//" are mapped to the "flowController" bean.
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="alwaysUseFullPath" value="true" />
<property name="mappings">
<value>/app/**/**=flowController</value>
</property>
</bean>
<bean name="flowController" class="org.springframework.webflow.mvc.servlet.FlowController">
<property name="flowExecutor" ref="flowExecutor" />
<property name="flowUrlHandler" ref="customDefaultUrlhandler" />
</bean>
<bean id="customDefaultUrlhandler" class="package.CustomDefaultFlowUrlHandler"/>
<flow:flow-executor id="flowExecutor" flow-registry="flowRegistry"/>
<flow:flow-builder-services id="flowBuilderServices" view-factory-creator="viewFactoryCreator" validator="validator"/>
<!-- Create the registry of flow definitions -->
<flow:flow-registry id="flowRegistry" base-path="/WEB-INF/flows/" flow-builder-services="flowBuilderServices">
<flow:flow-location-pattern value="**/*-flow.xml"/>
</flow:flow-registry>
See the flowUrlHandler being mapped to customDefaultUrlhandler which is an extension of DefaultFlowUrlHandler. The two methods which help to alter the flow url you specified in it are: getFlowId and createFlowDefinitionUrl.
Override the flowId and createFlowDefinitionUrl methods in DefaultFlowUrlHandler.
But this is all assuming your flow url is of type: somehost/{yourContextPath}/{yourServletContext}/widget/edit/99 where widget/edit is flowId and 99 is some widgetId.
public class CustomDefaultUrlhandler extends DefaultFlowUrlHandler{
You need to alter flowId and createFlowDefinitionUrl if request is something like this:
http://host/{yourContextPath}/{yourServletContext}/widget/edit/99 to direct to widget/edit flow
@Override
public String getFlowId(HttpServletRequest request) {
String pathInfo = request.getPathInfo(); // /widget/edit/99
if (pathInfo != null) {
String widgetId = pathInfo.substring(pathInfo.lastIndexOf("/") + 1);
if(widgetId != null){
return pathInfo.substring(1,pathInfo.lastIndexOf("/")); //return widget/edit by stripping /99
}else{
return pathInfo.substring(1); //return widget/edit
}
} else {
String servletPath = request.getServletPath();
if (StringUtils.hasText(servletPath)) {
int dotIndex = servletPath.lastIndexOf('.');
if (dotIndex != -1) {
return servletPath.substring(1, dotIndex);
} else {
return servletPath.substring(1);
}
} else {
String contextPath = request.getContextPath();
if (StringUtils.hasText(contextPath)) {
return request.getContextPath().substring(1);
} else {
return null;
}
}
}
}
@Override
public String createFlowDefinitionUrl(String flowId, AttributeMap input, HttpServletRequest request) {
//now flowId = "widget/edit"
StringBuffer url = new StringBuffer();
if (request.getPathInfo() != null) {
//for /{yourContextPath}/{yourServletContext}/widget/edit/99 - pathInfo is /widget/edit/99
url.append(request.getContextPath());
url.append(request.getServletPath());
url.append('/');
url.append(flowId);
} else {
String servletPath = request.getServletPath();
if (StringUtils.hasText(servletPath)) {
url.append(request.getContextPath());
url.append('/');
url.append(flowId);
int dotIndex = servletPath.lastIndexOf('.');
if (dotIndex != -1) {
url.append(servletPath.substring(dotIndex));
}
} else {
url.append('/');
url.append(flowId);
}
}
if (input != null && !input.isEmpty()) {
url.append('?');
if (request.getPathInfo() != null) {
//append your widget id here and retrieve this in flow by requestParameters el.
String widgetId = pathInfo.substring(pathInfo.lastIndexOf("/") + 1);
url.append("widgetId ="+widgetId);
}
appendQueryParameters(url, input.asMap(), getEncodingScheme(request));
}
return url.toString();
}
}
Basically we are customizing the flowid from your URL and passing the ids as request parameters.
Make sure your flow id is widget/edit in your scenario.
Check this link about how to get the flow id in desired format here : Spring Webflow - How to Get List of FLOW IDs