OmniFaces加载/卸载ViewScopedBean

时间:2018-07-17 13:42:55

标签: primefaces jsf-2.2 omnifaces

试图缩小问题范围,我们正在从Jboss 6 EAP(JSF 2.1)升级到Jboss 7 EAP(JSF 2.2)。现在,我们的工作应用程序遇到OmniFaces ViewScoped bean的问题。

版本:

  • Mojarra 2.2.14
  • OminFaces 2.6.9
  • PrimeFaces 6.2.5

我们有一个这样的数据表:

<p:dataTable id="tblLegalHolds" widgetVar="tableLegalHolds" var="row"
        rowKey="#{row.id}" filterEvent="enter" 
        lazy="true"
        value="#{bean.lazyDataModel}"
        rows="15">

注意::我们的bean是OmniFaces ViewScoped,此时我们的表工作正常!

问题: 接下来,我们添加一列,其中包含到新页面的导航,如下所示:

<p:column width="60" exportable="false">
    <p:button value="Open" outcome="legal-hold-edit">
        <f:param name="id" value="#{row.id}" />
    </p:button>
</p:column>

现在我们的bean正在立即加载和卸载,如果我们执行HTML的查看源代码,我们将看到Omnifaces脚本被添加了两次,就像这样...

OmniFaces.Unload.init('f1c1ff81-c87f-4406-b98f-a3eaff977e96');
OmniFaces.Unload.init('45e7de9d-53c7-4426-a972-797c48c46733');

我们在ViewScoped bean中添加了@PostConstruct,以证明它被两次调用。对于导航,我们的faces-config.xml看起来像这样。

<navigation-case>
    <from-outcome>legal-hold-edit</from-outcome>
    <to-view-id>/legal/legal-hold-edit.xhtml</to-view-id>
    <redirect include-view-params="true"/>
</navigation-case>

现在有趣的是,如果我们删除faces-config.xml中的“ include-view-params”,就像下面的代码一样,一切将开始正常运行,ViewScoped bean仅创建一次,并且只有1个OmniFaces.Unload.init脚本是添加到页面中。

<navigation-case>
    <from-outcome>legal-hold-edit</from-outcome>
    <to-view-id>/legal/legal-hold-edit.xhtml</to-view-id>
    <redirect/>
</navigation-case>

作为补充,我们的结果页使用o:viewparam接收如下参数:

    <f:metadata>
        <o:viewParam name="id" value="#{legalHoldForm.legalHold}" required="false" />
        <f:event type="preInvokeAction" listener="#{controller.initializeViewLegalHold}" />
   </f:metadata>

所以我的问题是:

  1. 为什么删除“ include-view-params”使其起作用?
  2. 这是与最近的ViewScoped问题类似的错误吗? :https://github.com/omnifaces/omnifaces/issues/463

2 个答案:

答案 0 :(得分:4)

这似乎是Mojarra中的错误。在找出另一个视图的视图参数时,它会间接调用PreDestroyViewMapEvent

在渲染响应阶段,将生成UIOutcomeTarget组件(例如<p:button>)的URL,并且将includeViewParams设置为true(已定义) (在您的导航情况下),则它需要查询目标视图的所有<f:viewParam>。为了实现这一点,它将需要构建一个UIViewRoot实例。

但是,实际上它是将新的UIViewRoot临时设置为人脸上下文的当前视图根,以便访问<f:viewParam>。它将恢复原始视图,但这就是Mojarra中出现问题的地方。 It is restoring context.setProcessingEvents(true) too early。实际上,它应该在还原原始视图之后

目前,最好的选择是针对Mojarra报告此问题,并避免将includeViewParams与OmniFaces @ViewScoped结合使用。

答案 1 :(得分:1)

问题报告:https://github.com/eclipse-ee4j/mojarra/issues/4503

公关提供:https://github.com/eclipse-ee4j/mojarra/pull/4730

此修复将包含在 Mojarra 的 2.3.15、3.0.1 和 4.0.0 中。