我编写了一个ViewScoped Managed-Bean,每当我在webbrowser中刷新页面时,Managed-Bean似乎都被重新创建,文章为null,它会加载一个新的文章对象,等等。对我而言,它看起来与RequestScoped的行为相同。
我将Eclipse IDE用于Java EE开发人员,最新的JDK,Apache Tomcat 7.0.8和Mojarra 2.0.3。
有什么问题?
托管bean:
...
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
...
@ManagedBean
@ViewScoped
public class CreateArticle {
@ManagedProperty(value = "#{index.facade}")
private PersistenceFacade facade;
private Article article;
private Vector<ArtCategory> artcat;
public CreateArticle() {
artcat = ArtCategory.listArtCat();
}
@PostConstruct
public void postCreateArticle() {
if (article == null) {
try {
article = facade.createArticle();
} catch (DAOException e) {
e.printStackTrace();
}
}
}
public void setFacade(PersistenceFacade facade) {
this.facade = facade;
}
public Vector<ArtCategory> getArtcat() {
return artcat;
}
public Article getArticle() {
return article;
}
public String save() {
try {
facade.save(article);
facade.commit();
} catch (DAOException e) {
e.printStackTrace();
}
FacesMessage message = new FacesMessage(
"Successful!");
FacesContext.getCurrentInstance().addMessage(null, message);
return "/testpage.xhtml";
}
}
createArticle.xhtml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>Create article</title>
</h:head>
<h:body>
<h1>
<h:outputText value="System" />
</h1>
<h2>
<h:outputText value="Test1" />
</h2>
<h3>
<h:outputText value="Test2" />
</h3>
<h:form>
<h:panelGrid columns="3">
<h:outputLabel for="artname">Articlename</h:outputLabel>
<h:inputText id="artname" value="#{createArticle.article.artname}"
required="true">
<f:ajax event="blur" render="artnameMessage" />
</h:inputText>
<h:message id="artnameMessage" for="artname" />
<h:outputLabel for="briefdesc">Brief description</h:outputLabel>
<h:inputTextarea id="briefdesc"
value="#{createArticle.article.briefdesc}" required="false">
<f:ajax event="blur" render="briefdescMessage" />
</h:inputTextarea>
<h:message id="briefdescMessage" for="briefdesc" />
<h:outputLabel for="price">Price</h:outputLabel>
<h:inputText id="price" value="#{createArticle.article.price}"
required="true">
<f:ajax event="blur" render="priceMessage" />
</h:inputText>
<h:message id="priceMessage" for="price" />
<h:outputLabel for="selectartcat">Article Category</h:outputLabel>
<h:selectOneMenu id="selectartcat"
value="#{createArticle.article.artcatnr}" required="true">
<f:selectItems value="#{createArticle.artcat}" var="artcat"
itemLabel="#{artcat.name}" itemValue="#{artcat.artcatnr}" />
<f:ajax event="blur" render="selectartcatMessage" />
</h:selectOneMenu>
<h:message id="selectartcatMessage" for="selectartcat" />
<h:panelGroup />
<h:commandButton value="Save"
action="#{createArticle.save}">
<f:ajax execute="@form" render="@form" />
</h:commandButton>
<h:messages globalOnly="true" layout="table" />
</h:panelGrid>
</h:form>
</h:body>
</html>
答案 0 :(得分:6)
这是预期的行为。当你通过在浏览器中刷新页面来解雇全新的HTTP GET请求时,它肯定会被重新创建。否则它会像会话范围的bean一样,它会使视图范围无用(想想不同浏览器选项卡中的新GET请求!)。但是,当您调用任何ajax请求或在同一视图中提交表单时,它将 not 重新创建。每次都会重新创建一个请求范围的请求。这是视图范围bean的核心点/优势。
答案 1 :(得分:1)
还要确保在ViewScoped bean上实现Serializable,就像使用SessionScoped bean一样。