JSF 2.0:为什么我的 ViewScope Bean 被重新创建,即使仍在同一视图上
在我的 .xhtml 页面中,我有以下形式:
<ui:composition xmlns:ui="http://java.sun.com/jsf/facelets"
template="./../template/CustomerTemplate.xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.prime.com.tr/ui">
<ui:define name="formContent">
<h:form>
<p:dataGrid var="item" value="#{mrBean.items}" columns="3">
<p:column>
<p:panel header="#{item.name}">
<h:panelGrid columns="1" style="width:100%">
...
<h:commandButton value="Add To Cart" actionListener="#{cartBean.addItem(item.id)}" />
...
</h:panelGrid>
</p:panel>
</p:column>
</p:dataGrid>
</h:form>
</ui:define>
</ui:composition>
CustomerTemplate.xhtml 是:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.prime.com.tr/ui">
<h:head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
... // import css, js files
</h:head>
<h:body>
... // Other things on the page
<div class="grid_9 content">
<ui:insert name="contentTitle"></ui:insert>
<ui:insert name="formContent"></ui:insert>
</div>
...
</h:body>
</html>
这是我的 ManagedBean:
@ManagedBean
@ViewScoped
public class MrBean {
...
private List<ItemState> items;
...
@PostConstruct
public void prepareItemList() {
...
Map<String,String> params = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
partnerID = Long.parseLong(params.get("partnerID"));
...
}
}
如您所见,我的 MrBean 是一个 ViewScoped ManagedBean。我预计 @PostContruct 函数只会在第一次渲染页面时调用一次。但是,当我单击 Add To Cart
按钮时,我在 Long.parseLong(params.get("partnerID"))
行遇到了 null 异常,即使我我仍然在同一个视图上。
如果有人能给我关于如何解决这个问题的建议,我将不胜感激。
更新:我设法通过将 commandButton
包装在 ajax
标记内来使该功能正常工作,如下所示:
...
<f:ajax listener="#{cartManagedBean.addItem(item.id)}">
<h:commandButton value="Add To Cart" />
</f:ajax>
....
In my .xhtml page, I have the following form:
<ui:composition xmlns:ui="http://java.sun.com/jsf/facelets"
template="./../template/CustomerTemplate.xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.prime.com.tr/ui">
<ui:define name="formContent">
<h:form>
<p:dataGrid var="item" value="#{mrBean.items}" columns="3">
<p:column>
<p:panel header="#{item.name}">
<h:panelGrid columns="1" style="width:100%">
...
<h:commandButton value="Add To Cart" actionListener="#{cartBean.addItem(item.id)}" />
...
</h:panelGrid>
</p:panel>
</p:column>
</p:dataGrid>
</h:form>
</ui:define>
</ui:composition>
The CustomerTemplate.xhtml is:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.prime.com.tr/ui">
<h:head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
... // import css, js files
</h:head>
<h:body>
... // Other things on the page
<div class="grid_9 content">
<ui:insert name="contentTitle"></ui:insert>
<ui:insert name="formContent"></ui:insert>
</div>
...
</h:body>
</html>
And this is my ManagedBean:
@ManagedBean
@ViewScoped
public class MrBean {
...
private List<ItemState> items;
...
@PostConstruct
public void prepareItemList() {
...
Map<String,String> params = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
partnerID = Long.parseLong(params.get("partnerID"));
...
}
}
As you can see, my MrBean is a ViewScoped ManagedBean. I expected that the @PostContruct function will only be called once when the page is 1st rendered. However, when I click the Add To Cart
button, I ran into the null exception at the line Long.parseLong(params.get("partnerID"))
even though I am still on the same View.
I'd be very grateful if someone could give me an advice on how to tackle this problem.
UPDATE: I managed to get the function working by wrapping the commandButton
inside an ajax
tag like following:
...
<f:ajax listener="#{cartManagedBean.addItem(item.id)}">
<h:commandButton value="Add To Cart" />
</f:ajax>
....
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
造成这种情况的可能原因有很多,最终都归结为先有鸡还是先有蛋的问题,如 中所述。 JSF 问题 1492。您正在使用
将 UI 组件绑定到视图范围的托管 bean 属性,或者您正在绑定标记处理程序的属性,例如
、
等到视图作用域托管 bean 属性。计划在 JSF 2.2 中修复此问题。在此之前,最好的选择是寻找替代方法或将上下文参数 javax.faces.PARTIAL_STATE_SAVING 设置为 false。
另请参阅:
There are a lot of possible reasons for this which all ultimately boils down to the chicken-egg issue as described in JSF issue 1492. You are using
<h:someHtmlComponent binding="...">
to bind an UI component to a view scoped managed bean property, or you are binding an attribute of a tag handler like<c:if test="...">
,<ui:include src="...">
, etc to a view scoped managed bean property.This is scheduled to be fixed in JSF 2.2. Until then, your best bet is to look for alternative approaches or to set the context parameter
javax.faces.PARTIAL_STATE_SAVING
tofalse
.See also: