我想主要使用Spring Web Flow来实现其PRG功能。
我们说我有/widget/edit/99
或/widget/edit/123
等网址,其中数字代表小工具的id
。
如何启动/widget/edit
流程,传入id
?
默认情况下,流URL看起来必须与流名称文件夹结构匹配。
我希望将网址保留在/widget/edit/99
,而不是重定向。
(使用v 2.4)
答案 0 :(得分:6)
您需要尝试使用FlowController和DefaultFlowUrlHandler。
FlowController - 它充当Web Flow定义的控制逻辑和DispatcherServlet的网关。
根据文档,DefaultFlowUrlHandler中的createFlowDefinitionUrl方法:
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
因此,如果请求如下:somehost / yourContextPath / yourServletContext / widget / edit / 99且flow id是widget / edit,则新的流定义URL将是:somehost / yourContextPath / yourServletContext / widget / edit
假设某些配置为:
web.xml配置将“/ widgetinventory / *”请求映射到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中: 具有与“/ widgetinventory / / ”匹配的servlet路径的所有请求都映射到“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>
请参阅映射到customDefaultUrlhandler的flowUrlHandler,它是DefaultFlowUrlHandler的扩展名。有助于更改您在其中指定的流URL的两种方法是:getFlowId和createFlowDefinitionUrl。
覆盖DefaultFlowUrlHandler中的flowId和createFlowDefinitionUrl方法。
但这是假设您的流URL类型为:somehost / {yourContextPath} / {yourServletContext} / widget / edit / 99其中widget / edit为flowId,99为某个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();
}
}
基本上我们是从您的URL自定义flowid并将id作为请求参数传递。
确保您的方案中的流ID是小部件/编辑。
在此处查看此链接,了解如何以所需格式获取流ID:Spring Webflow - How to Get List of FLOW IDs
答案 1 :(得分:1)
请参阅,topic请考虑使用spring mvc,在Spring MVC中,您可以在方法参数上使用@PathVariable注释将其绑定到URI模板变量的值:
e.g
@RequestMapping(value="/owners/{ownerId}", method=RequestMethod.GET)
public String findOwner(@PathVariable String ownerId, Model model) {
Owner owner = ownerService.findOwner(ownerId);
model.addAttribute("owner", owner);
return "displayOwner";
}
URI模板“/ owners / {ownerId}”指定变量名称ownerId。当控制器 处理此请求时,ownerId的值设置为在URI的相应部分中找到的值。 例如,当/ owner / fred的请求进入时,ownerId的值为fred。
@PathVariable参数可以是任何简单类型,例如int,long,Date等.Spring 如果无法执行,则自动转换为适当的类型或抛出TypeMismatchException 所以。您还可以注册支持解析其他数据类型。请参阅“方法”一节 参数和类型转换“和”自定义WebDataBinder初始化“一节。
请参阅有关PathVariable的Here文档。