如何使用Faces-Redirect输入JSF 2.2流 [英] How to enter a JSF 2.2 flow with faces-redirect

查看:151
本文介绍了如何使用Faces-Redirect输入JSF 2.2流的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个基本的流程示例正在工作:

I've got a basic flow example working:

src/main/webapp
|
|- index.xhtml
|- flow1
   |- flow1-flow.xml
   |- flow1.xhtml

index.xhtml具有一个简单的形式,该形式使用参数输入流:

index.xhtml has a simple form that enters the flow with a parameter:

<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显示参数,并允许您在流范围中输入一个值:

flow1.xhtml displays the param and lets you enter a value into flow scope:

<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.

flow1-flow.xml just defines the return node as "returnFromFlow1" and sets it to /index.xhtml.

这似乎有效.我想在输入流时实现post-redirect-get,以便浏览器地址栏与视图保持同步.因此,我自然尝试了action ="flow1?faces-redirect = true".此更改阻止了流程的执行.单击按钮时,它只是重新加载index.xhtml.

This seems to be working. I want to implement post-redirect-get when entering the flow so that the browser address bar stays in sync with the view. So I naturally tried action="flow1?faces-redirect=true". This change prevents the flow from executing.. it simply reloads index.xhtml when the button is clicked.

然后我尝试了action ="flow1/flow1.xhtml?faces-redirect = true".这将加载页面并按预期进行重定向,但流程尚未初始化.在流程中提交表单时,出现关于flowScope解析为null的错误.

Then I tried action="flow1/flow1.xhtml?faces-redirect=true". This loads the page and redirects as expected, but the flow is not initialized. When I submit the form in the flow, I get an error about flowScope resolving to null.

做了一些研究,我发现了一个技巧来设置"to-flow-document-id",以强制其初始化流程.因此,我添加了我的命令按钮.没变化.

Doing a little research, I found a tip to set the "to-flow-document-id" to force it to initialize the flow. So I added to my commandbutton. No change.

关于如何实现此目标的任何想法?

Any ideas about how to accomplish this?

推荐答案

如果唯一的要求是浏览器地址栏与视图保持同步,则可以简单地使用<h:button而不是<h:commandButton.之所以可行,是因为<h:button使用Javascript生成HTTP GET请求以启动并导航至该流程.流的ID必须指定为outcome属性的值:

If the only requirement is that the browser address bar stays in sync with the view, you can simply use <h:button instead of <h:commandButton. This works because <h:button uses Javascript to generate a HTTP GET request to start and navigate to the flow. The ID of the flow has to be specified as value of the outcome attribute:

index.xhtml:

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之间的区别
  • See also:

    • Difference between h:button and h:commandButton
    • 如果要求在开始启动流的权限之前必须进行一些检查,则必须手动初始化并导航到该流,如下所示:

      If the requirement is that some checks have to be done before the permission to start the flow is granted, you have to manually initialize and navigate to the flow as follows:

      index.xhtml:

      index.xhtml:

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

      flow1.xhtml:

      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:

      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);
      }
      

      请注意,在这种情况下,不能将参数添加到按钮,而必须将其添加到流作用域! 还请注意,必须通过

      Please note that the parameter can not be added to the button in this case but has to be added to the flow scope instead! Also note that the redirect to the flow has to be done by NavigationHandler#handleNavigation() instead of ExternalContext#redirect() because the flow scope is terminated otherwise!

      这篇关于如何使用Faces-Redirect输入JSF 2.2流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆