我想我遇到了Mojarra 2.1.0中的一個bug。也許我錯過了一些東西,但是如果我能看到它,該死的。使用JSTL /核心標籤擰起來ViewScoped Bean
我依靠很多@ViewScoped bean來保存狀態,同時瀏覽器爲服務器做了很多AJAX。我發現當我使用某些標記時,@ViewScoped bean在不應該出現時開始重新實例化。這裏是我的測試案例支持bean:
/*
* TestStuff.java
*/
package test;
import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.event.ActionEvent;
/**
* Backing bean for test.xhtml -- working out AJAX/SVG connection
*
*/
@ManagedBean
@ViewScoped
public class TestStuff implements Serializable {
private int counter = 0;
public TestStuff() {
log("TestStuff(): {0}", this);
}
public String getRandomNumber() {
int i = (int) (Math.random() * 1000000.0);
return String.format("%d", i);
}
public int getCounter() { return counter; }
public List<String> getStuff() {
return Arrays.asList("big", "bad", "wolf");
}
public void pushButton(ActionEvent evt) {
log("TestStuff.pushButton({0}): {1}",
new Object[] { evt, ++counter });
}
}
這裏是使用它的JSF的Facelets頁:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.prime.com.tr/ui"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:c="http://java.sun.com/jsp/jstl/core">
<h:head>
<title>Test Page</title>
</h:head>
<h:body>
<h1>Test Page</h1>
<p>If you are reading this text, the server
is not properly configured.</p>
<ui:composition id="compRoot" template="/template5.xhtml">
<ui:define name="content">
<h1>Test</h1>
<h:form id="formTest">
<p:commandButton value="Do Me"
actionListener="#{testStuff.pushButton}"
update="testUpdate" />
<p:panel id="testUpdate" >
<h:outputText value="Random output is: " />
<h:outputText
value="#{testStuff.randomNumber}"
/>
<h:outputText value=" Counter is: "/>
<h:outputText
value="#{testStuff.counter}"
/>
</p:panel>
<h:panelGrid columns="5" border="1" >
<c:forEach items="#{testStuff.stuff}" var="x">
<h:outputText value="#{x}" />
</c:forEach>
</h:panelGrid>
</h:form>
</ui:define>
</ui:composition>
</h:body>
</html>
因此,這裏是哪裏出了問題。當你點擊「Do Me」命令按鈕時,每次都會創建一個支持bean的新實例,就像它是一個@RequestScoped bean一樣。我可以通過構造函數中的log()調用來看到這一點。
如果將bean更改爲@SessionScoped,則不會發生這種情況。無論按鈕被點擊多少次,您都會獲得一個bean實例。但是,如果您將其保留爲@ViewScoped,並且您將c:foreach元素及其內容取出,則它現在不再重新實例化該bean的每次單擊。換句話說,它現在按預期工作。
這是一個莫哈拉錯誤還是我在這裏做錯了什麼?
我從ui開始:重複,但問題是它將整個集合視爲單個組件。換句話說,如果它在h:panelGrid中,您將得到一個包含一個單元格的表格。謝謝,雖然我認爲我可以解決這個問題,但它確實讓我發瘋,並且很高興知道這是一個真正的問題。 – AlanObject 2011-05-18 04:15:58