Java SpringWebFlow如何在退出flow到外部重定向时添加flash属性
我是SpringWebFlow(2.3.1)的新手,这就是我要做的: 我有一个JSP页面,它在页面底部为页面顶部选择的作者列出了一个分页的图书表。我在顶部的“添加书籍”(就在作者下拉列表的下方)有一个按钮/链接,单击该按钮/链接将启动一个Spring web流,进入一个页面,用户可以在步骤1、2和3中输入书籍的详细信息(在3个不同的视图/页面中)。单击“保存”将创建新书,并应使用户返回带有分页图书列表的视图 现在,我想在保存操作之后添加一个flash属性(成功消息),并将用户带回图书页面(分页),预先选择“上一位”作者并显示成功消息 我为最终状态提供了以下web流XML:Java SpringWebFlow如何在退出flow到外部重定向时添加flash属性,java,jsp,spring-mvc,tiles,spring-webflow-2,Java,Jsp,Spring Mvc,Tiles,Spring Webflow 2,我是SpringWebFlow(2.3.1)的新手,这就是我要做的: 我有一个JSP页面,它在页面底部为页面顶部选择的作者列出了一个分页的图书表。我在顶部的“添加书籍”(就在作者下拉列表的下方)有一个按钮/链接,单击该按钮/链接将启动一个Spring web流,进入一个页面,用户可以在步骤1、2和3中输入书籍的详细信息(在3个不同的视图/页面中)。单击“保存”将创建新书,并应使用户返回带有分页图书列表的视图 现在,我想在保存操作之后添加一个flash属性(成功消息),并将用户带回图书页面(分页)
<end-state id="home" view="externalRedirect:/books/" >
<output name="author" value="book.author" />
</end-state>
“output”标记将用作在子流和父流调用者之间传输POJO的容器。但是,以下增强请求: 扩展了“output”标记的角色,以允许将flash变量从webflow的“结束状态”传输到springmvc控制器的flashMap 不幸的是,此增强没有包括您想要实现的功能,即通过externalRedirect从flow A->new flow A传递变量。因此,对于任何没有所需功能的第三方库。。。我们必须“破解”它 1。首先,您需要按照以下方式配置FlowHandlerAdapter,以利用上述增强功能: 设置为true的“SaveOutputOfLashScopeOnRedirect”是本次讨论的重要部分(默认设置为false)
2。您需要创建(扩展)和配置FlowExecutionListenerAdapter
import java.util.Map;
import java.util.Map.Entry;
import javax.servlet.http.HttpServletRequest;
import org.springframework.web.servlet.support.RequestContextUtils;
import org.springframework.webflow.core.collection.MutableAttributeMap;
import org.springframework.webflow.core.collection.SharedAttributeMap;
import org.springframework.webflow.definition.FlowDefinition;
import org.springframework.webflow.execution.FlowExecutionListenerAdapter;
import org.springframework.webflow.execution.RequestContext;
public class TestFlowExecutionListenerAdapter extends FlowExecutionListenerAdapter{
@Override
public void sessionCreating(RequestContext context, FlowDefinition definition) {
MutableAttributeMap<Object> flashScopeWebFlow = context.getFlashScope();
MutableAttributeMap<Object> flashMapWebFlow = context.getFlowScope();
SharedAttributeMap<Object> sessionMap = context.getExternalContext().getSessionMap();
MutableAttributeMap<Object> requestMap = context.getExternalContext().getRequestMap();
HttpServletRequest request = (HttpServletRequest)context.getExternalContext().getNativeRequest();
Map<String, ?> flashMapMvc = RequestContextUtils.getInputFlashMap(request);
if(flashMapMvc != null)
putAllFlashMapToFlashScope(flashMapMvc,flashScopeWebFlow);
System.out.println("here");
}
public static void putAllFlashMapToFlashScope(Map<String, ?> map, MutableAttributeMap<Object> mutableAttributeMap) {
for( Entry<String, ?> entry : map.entrySet()) {
mutableAttributeMap.put(entry.getKey(), entry.getValue());
}
}
}
import java.util.Map;
导入java.util.Map.Entry;
导入javax.servlet.http.HttpServletRequest;
导入org.springframework.web.servlet.support.RequestContextUtils;
导入org.springframework.webflow.core.collection.MutableAttributeMap;
导入org.springframework.webflow.core.collection.SharedAttributeMap;
导入org.springframework.webflow.definition.FlowDefinition;
导入org.springframework.webflow.execution.FlowExecutionListenerAdapter;
导入org.springframework.webflow.execution.RequestContext;
公共类TestFlowExecutionListenerAdapter扩展了FlowExecutionListenerAdapter{
@凌驾
public void sessionCreating(RequestContext上下文,FlowDefinition){
MutableAttributeMap flashScopeWebFlow=context.getFlashScope();
MutableAttributeMap flashMapWebFlow=context.getFlowScope();
SharedAttributeMap sessionMap=context.getExternalContext().getSessionMap();
MutableAttributeMap requestMap=context.getExternalContext().getRequestMap();
HttpServletRequest=(HttpServletRequest)context.getExternalContext().getNativeRequest();
Map flashMapMvc=RequestContextUtils.getInputFlashMap(请求);
如果(flashMapMvc!=null)
PutalFlashMapToFlashScope(flashMapMvc、flashScopeWebFlow);
System.out.println(“此处”);
}
public static void putAllFlashMapToFlashScope(映射映射,MutableAttributeMap MutableAttributeMap){
for(条目:map.entrySet()){
mutableAttributeMap.put(entry.getKey(),entry.getValue());
}
}
}
初始化bean,如下所示:
<webflow:flow-executor id="flowExecutor" flow-registry="flowRegistry">
<webflow:flow-execution-listeners>
<webflow:listener ref="testFlowExecutionListenerAdapter" />
</webflow:flow-execution-listeners>
</webflow:flow-executor>
<bean id="testFlowExecutionListenerAdapter" class="com.foo.bar.flowexeclisteners.TestFlowExecutionListenerAdapter"/>
注意:将“com.foo.bar.flowexeclisteners”更改为实际的包路径
3.上面的FlowExecutionListenerAdapter允许@Overriding某些方法来监视SpringWebFlow框架的生命周期事件。在我们的例子中,我选择@Override sessionCreating()方法,但是您可以使用许多不同的方法来满足您的用例或提高效率
鉴于上述配置,我们现在可以开始以两种方式传回变量。一个是通过sessionMap,另一个是通过“output”标记,该标记现在配置为存储在flashMap中(SpringMVC而不是flashScope)。下面是一个“结束状态”示例,演示了这一点
<end-state id="home" view="externalRedirect:/books/">
<on-entry>
<evaluate expression="externalContext.sessionMap.put('author', 'William Brian Jennings')"/>
</on-entry>
<output name="responseMsg" value="'Added author to the sessionMap'"/>
</end-state>
4.触发此“结束状态”时(如果您在FlowExecutionListenerAdapter中放置断点),您将看到flashMapMvc将保存您的“responseMsg”变量,而“author”变量将位于sessionMap中。静态方法“putAllFlashMapToFlashScope”将自动使您的“responseMsg”可供视图使用,但对于sessionMap,您需要在接收流中显式提取变量,如下所示:
<set name="flowScope.author" value="externalContext.sessionMap.get('author')"/>
以下是一些注意事项:
<end-state id="home" view="externalRedirect:/books/">
<on-entry>
<evaluate expression="externalContext.sessionMap.put('author', 'William Brian Jennings')"/>
</on-entry>
<output name="responseMsg" value="'Added author to the sessionMap'"/>
</end-state>
<set name="flowScope.author" value="externalContext.sessionMap.get('author')"/>