如何使用 faces-redirect 进入 JSF 2.2 流程

2023-11-27

我有一个基本的流程示例:

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。

这似乎有效。我想在进入流程时实现 post-redirect-get ,以便浏览器地址栏与视图保持同步。所以我很自然地尝试了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属性:

索引.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 之间的区别

如果要求在授予启动流程的权限之前必须完成一些检查,则必须手动初始化并导航到流程,如下所示:

索引.xhtml:

<h:form>
    Click to enter flow1
    <h:commandButton action="#{backingBean.startFlow1()}" value="Flow 1" />
</h:form>

流程1.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>

支持Bean:

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 按结果
  • Omnifaces Faces.redirect 失去对话范围
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 faces-redirect 进入 JSF 2.2 流程 的相关文章

随机推荐