【问题标题】:How to start special init event in a backing bean before JSF page loads?如何在 JSF 页面加载之前在支持 bean 中启动特殊的 init 事件?
【发布时间】:2013-08-31 16:48:17
【问题描述】:

PF 3.5.10、Mojarra 2.1.21、Omnifaces 1.5

如何在加载 .xhtml JSF 页面之前调用某些 (CDI)SessionScoped bean 的特殊 init() 方法?如果用户从站点菜单中选择页面(使用p:menutitem),现在我调用 init()。但是如果用户使用浏览器地址行直接输入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 的解决方案,正如 cmets 所述,Omnifaces 1.6 也将具有 ViewScope。

【问题讨论】:

    标签: jsf jsf-2 cdi


    【解决方案1】:

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

    一种解决方法是使用&lt;f:event type="preRenderView" listener="{bean.init}" /&gt;,如下所述:What can <f:metadata>, <f:viewParam> and <f:viewAction> be used for?(无需使用&lt;f:metadata&gt;,如 BalusC 所述:Does it matter whether place f:event inside f:metadata or not?)。

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

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

    如果您迁移到 JSF 2.2,则有 a @ViewScoped annotation for CDI beans,您可以相应地缩小 @SessionScoped bean 的范围。

    【讨论】:

    • 顺便说一下,OmniFaces 1.6 将附带一个 CDI 兼容 @ViewScoped 用于 JSF 2.0/2.1。
    • @BalusC 你最后的评论是个好消息。我会等待并尝试它。
    • 这已经在“ 可以用来做什么?”中得到回答/解释。链接:)
    • @BalusC 好的,我明白了。我应该在 init() 中进行回发检查。我会试试的。
    猜你喜欢
    • 1970-01-01
    • 2014-05-29
    • 2012-01-30
    • 2011-05-01
    • 2019-10-03
    • 2018-04-04
    • 2015-08-23
    • 2023-03-23
    • 2012-08-03
    相关资源
    最近更新 更多