3

PF 3.5.10、Mojarra 2.1.21、Omnifaces 1.5

在加载 .xhtml JSF 页面之前,如何调用某些 (CDI)SessionScoped bean 的特殊 init() 方法?现在,如果用户从站点菜单(使用 )中选择页面,我会调用 init( p:menutitem)。但是如果用户使用浏览器地址行直接输入url怎么办?

编辑my.xhtml::

<ui:define template="/mytemp.xhtml">
   <f:event type="preRenderView" listener="#{mybean.init()}" />
   <h:form>
     <p:commandButton update="@form" ... />
   </h:form>
</ui:define>

如果我这样做,init() 将在每次更新时调用(即在每次回发到服务器时),例如在每次单击命令按钮时。所以我不能使用你的建议。

编辑 2:谢谢 Luiggi Mendoza 和 BalusC!除了 Luiggi Mendoza 的解决方案,正如评论中所说,Omnifaces 1.6 也将具有 ViewScope。

4

1 回答 1

9

问题是在@PostConstruct public void init()创建托管 bean 并注入字段之后调用该方法。由于您的 bean 是@SessionScoped,它将一直存在到用户会话到期。

一种解决方法是<f:event type="preRenderView" listener="{bean.init}" />按照此处的说明使用:<f:metadata>、<f:viewParam> 和 <f:viewAction> 可以用于什么?(不需要<f:metadata>按照 BalusC 的解释在这里使用:是否将 f:event 放在 f:metadata 中是否重要?)。

根据您的问题更新,此问题在第一个链接中处理。我将发布相关代码来处理这种情况(取自 BalusC 答案):

public void init() {
    FacesContext facesContext = FacesContext.getCurrentInstance();
    if (!facesContext.isPostback() && !facesContext.isValidationFailed()) {
        // ...
    }
}

如果您迁移到 JSF 2.2,那么有一个@ViewScopedCDI bean 注释,您可以相应地缩小@SessionScopedbean 的范围。

于 2013-08-28T14:38:41.190 回答