我已经有了一个基本的流程示例:
src/main/webapp
|
|- index.xhtml
|- flow1
|- flow1-flow.xml
|- flow1.xhtml
index.xhtml有一个简单的表单,它通过一个参数进入流:
<h:form>
Click to enter flow1
<h:commandButton action="flow1" value="Flow 1">
<f:param name="testInput" value="hi there"/>
</h:commandButton>
</h:form>
flow1.xhtml显示参数,并允许您在流范围内输入一个值:
<h:form>
Hi this is page 1.
<h:inputText label="Enter something:" value="#{flowScope.testOutput}"/><br/>
Request parameter: #{param['testInput']}<br/>
<h:commandButton action="returnFromFlow1"/>
</h:form>
flow1-flow.xml只是将返回节点定义为"returnFromFlow1"并将其设置为/index.xhtml。
这似乎是工作。我想在进入流时实现后重定向-获取,以便浏览器地址栏与视图保持同步。所以我很自然地尝试了action="flow1?faces-redirect=true"。此更改将阻止流执行。它只是在单击按钮时重新加载index.xhtml。
然后我尝试了action="flow1/flow1.xhtml?faces-redirect=true"。这将加载页面并按预期重定向,但未初始化流。当我在流中提交表单时,我得到一个关于flowScope解析为null的错误。
做了一点研究,我发现了一个技巧,设置"to-flow-document-id"来强制它初始化流。所以我添加了命令按钮。没有变化。
关于如何实现这一点有什么想法吗?
如果唯一的要求是浏览器地址栏与视图保持同步,您可以简单地使用<h:button
而不是<h:commandButton
。这是因为<h:button
使用Javascript生成一个HTTP GET请求来启动和导航到流。流的ID必须指定为outcome
属性的值:
index.xhtml:
<h:form>
Click to enter flow1
<h:button outcome="flow1" value="Flow 1">
<f:param name="testInput" value="hi there" />
</h:button>
</h:form>
参见:
- h:button与h:commandButton的区别
如果需求是在授予启动流的权限之前必须进行一些检查,则必须手动初始化并导航到流,如下所示:
index.xhtml:
<h:form>
Click to enter flow1
<h:commandButton action="#{backingBean.startFlow1()}" value="Flow 1" />
</h:form>
flow1.xhtml:
<h:form>
Hi this is page 1.
<h:inputText label="Enter something:" value="#{flowScope.testOutput}"/><br/>
Request parameter: #{flowScope.testInput}<br/>
<h:commandButton action="returnFromFlow1"/>
</h:form>
BackingBean:
public void startFlow1() {
if (!permissionGranted) {
// show "permission denied"
return;
}
final FacesContext facesContext = FacesContext.getCurrentInstance();
final Application application = facesContext.getApplication();
// get an instance of the flow to start
final String flowId = "flow1";
final FlowHandler flowHandler = application.getFlowHandler();
final Flow targetFlow = flowHandler.getFlow(facesContext,
"", // definingDocumentId (empty if flow is defined in "faces-config.xml")
flowId);
// get the navigation handler and the view ID of the flow
final ConfigurableNavigationHandler navHandler = (ConfigurableNavigationHandler) application.getNavigationHandler();
final NavigationCase navCase = navHandler.getNavigationCase(facesContext,
null, // fromAction
flowId);
final String toViewId = navCase.getToViewId(facesContext);
// initialize the flow scope
flowHandler.transition(facesContext,
null, // sourceFlow
targetFlow,
null, // outboundCallNode
toViewId); // toViewId
// add the parameter to the flow scope
flowHandler.getCurrentFlowScope()
.put("testInput", "hi there2!");
// navigate to the flow by HTTP GET request
final String outcome = toViewId + "?faces-redirect=true";
navHandler.handleNavigation(facesContext,
null, // from action
outcome);
}
请注意,在这种情况下,参数不能添加到按钮中,而必须添加到流作用域中!还请注意,对流的重定向必须由NavigationHandler#handleNavigation()
而不是ExternalContext#redirect()
完成,因为否则流作用域将终止!
参见:
- 可以在Servlet中启动faces流吗? 以编程方式从faces-config.xml by outcome
- Omnifaces面孔。重定向失去会话作用域
嗯,如果我正确地阅读了JSF-2.2 faces-config模式,您应该能够在faces-config.xml中指定<redirect/>
指令。因此,使用以下命令,您应该能够实现重定向:
<navigation-rule>
<from-view-id>/pages/test/test.xhtml</from-view-id>
<navigation-case>
<from-outcome>flow1</from-outcome>
<to-flow-document-id>flow1.xhtml</to-flow-document-id>
<redirect />
</navigation-case>
</navigation-rule>
请运行这个例子,我希望它能帮助你。
<navigation-rule>
<navigation-case>
<from-outcome>flow1</from-outcome>
<to-view-id>flow1.xhtml</to-view-id>
<redirect></redirect>
</navigation-case>
</navigation-rule>