PF 3.5.10,Mojarra 2.1.21,Omnifaces 1.5
如何在加载.xhtml JSF页面之前调用特殊的init() - 某些(CDI)SessionScoped bean的方法?现在我调用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()将在每次更新时调用(即在每次回发到服务器时),例如每次单击commandButton时。所以我不能使用你的提议。
编辑2:谢谢Luiggi Mendoza和BalusC! 除了Luiggi Mendoza的解决方案之外,正如评论所述,Omnifaces 1.6也将拥有ViewScope。
答案 0 :(得分:9)
问题是在创建托管bean并注入字段后调用@PostConstruct public void init()
方法。由于您的bean是@SessionScoped
,它将一直存在,直到用户会话到期。
解决方法是使用<f:event type="preRenderView" listener="{bean.init}" />
,如下所示:What can <f:metadata>, <f:viewParam> and <f:viewAction> be used for?(无需使用BalusC在此解释的<f:metadata>
: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的范围。