经过一些实验,这似乎是使用 CDI bean 时的一个问题,与我最初假设的 PrimeFaces 无关。
如果我使用 @ManagedBean 将 TableBeanLazy 更改为托管 Bean,那么构造函数和 @PostConstruct 方法只会被调用一次,正如我所期望的那样。
任何人都可以对此有所了解吗?
==================================================== =
我对 JSF 和 PrimeFaces 还很陌生,因此将不胜感激任何指导。我搜索了其他帖子,并阅读了许多类似的帖子,但找不到解决方案。
我试图让 PrimeFaces Showcase 网站上的延迟加载数据表示例在我的项目中工作,但由于 bean 类的行为不符合我的预期,我遇到了问题。
我对 PrimeFaces 站点的示例代码进行了一些更改:- 将 TableBean 类重命名为 TableBeanLazy;为类添加注释;分配的静态字符串数组;将初始化从构造函数移至 @PostConstruct initialise() 方法;分配汽车成员变量。
我还在构造函数和 @PostConstruct 方法中添加了跟踪消息,这些消息表明,当第一次显示表格时,它们都被多次调用,每次单击搜索图标时都会被调用多次,并且每个字符条目都会被调用多次过滤字段。
这会导致每次执行操作时都会重新创建 Car 对象的随机列表,因此排序和过滤永远不会产生预期的结果 - 它们在 PrimeFaces Showcase 站点上直接运行示例时会这样做。
虽然我最初使用的是@ViewScoped,但我也尝试了@RequestScoped,最后尝试了@SessionScoped,但它们的行为方式都相同。
对构造函数和 @PostConstruct 的多次调用是 bean 的预期行为吗?
如果是这样,PrimeFaces Showcase 网站上给出的示例代码如何工作?
我该如何解决这个问题?
环境
PrimeFaces 3.5
JSF 2.1
JDK 1.7
GlassFish Server Open Source Edition 3.1.2.2 (build 5)
Mojarra 2.1.6 (SNAPSHOT 20111206)
Netbeans IDE 7.3
Windows 7 Pro x64
MyTable.xhtml
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
template="./resources/templates/platform_tpl.xhtml"
xmlns:p="http://primefaces.org/ui"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<ui:define name="body">
<h2 style="margin-top: 0px; padding-top: 0px;">Cars List</h2>
<h:form id="form">
<p:dataTable var="car" value="#{tableBeanLazy.lazyModel}" paginator="true" rows="10"
paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}"
rowsPerPageTemplate="5,10,15" selectionMode="single" selection="#{tableBeanLazy.selectedCar}" id="carTable" lazy="true">
<p:column headerText="Model" sortBy="#{car.model}" filterBy="#{car.model}">
<h:outputText value="#{car.model}" />
</p:column>
<p:column headerText="Year" sortBy="#{car.year}" filterBy="#{car.year}">
<h:outputText value="#{car.year}" />
</p:column>
<p:column headerText="Manufacturer" sortBy="#{car.manufacturer}" filterBy="#{car.manufacturer}">
<h:outputText value="#{car.manufacturer}" />
</p:column>
<p:column headerText="Color" sortBy="#{car.color}" filterBy="#{car.color}">
<h:outputText value="#{car.color}" />
</p:column>
</p:dataTable>
</h:form>
</ui:define>
</ui:composition>
TableBeanLazy.java
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package BackEnd;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.SessionScoped;
import javax.inject.Named;
import org.primefaces.model.LazyDataModel;
@Named(value = "tableBeanLazy")
@SessionScoped
public class TableBeanLazy
{
static String[] colors = new String[10];
static String[] manufacturers = new String[10];
static String[] models = new String[5];
private LazyDataModel<Car> lazyModel;
private Car selectedCar;
private List<Car> cars;
static
{
colors[0] = "Black";
colors[1] = "White";
colors[2] = "Green";
colors[3] = "Red";
colors[4] = "Blue";
colors[5] = "Orange";
colors[6] = "Silver";
colors[7] = "Yellow";
colors[8] = "Brown";
colors[9] = "Maroon";
manufacturers[0] = "Mercedes";
manufacturers[1] = "BMW";
manufacturers[2] = "Volvo";
manufacturers[3] = "Audi";
manufacturers[4] = "Renault";
manufacturers[5] = "Opel";
manufacturers[6] = "Volkswagen";
manufacturers[7] = "Chrysler";
manufacturers[8] = "Ferrari";
manufacturers[9] = "Ford";
models[0] = "Sports";
models[1] = "Saloon";
models[2] = "SUV";
models[3] = "Hybrid";
models[4] = "Estate";
}
public TableBeanLazy()
{
System.out.println("--> In constructor for TableBeanLazy");
}
@PostConstruct
public void initialise()
{
System.out.println("--> In initialise for TableBeanLazy");
cars = new ArrayList<Car>();
populateRandomCars(cars, 5);
lazyModel = new LazyCarDataModel(cars);
}
public Car getSelectedCar()
{
return selectedCar;
}
public void setSelectedCar(Car selectedCar)
{
this.selectedCar = selectedCar;
}
public LazyDataModel<Car> getLazyModel()
{
return lazyModel;
}
private void populateRandomCars(List<Car> list, int size)
{
System.out.println("--> In populateRandomCars for TableBeanLazy");
for(int i = 0 ; i < size ; i++)
{
list.add(new Car(getRandomModel(), getRandomYear(), getRandomManufacturer(), getRandomColor()));
}
}
private String getRandomColor()
{
return colors[(int)(Math.random() * 10)];
}
private String getRandomManufacturer()
{
return manufacturers[(int) (Math.random() * 10)];
}
private String getRandomModel()
{
return models[(int)(Math.random() * 5)];
}
private int getRandomYear()
{
return (int)(Math.random() * 50 + 1960);
}
}
表格初始显示时的输出
INFO: --> In constructor for TableBeanLazy
INFO: --> In initialise for TableBeanLazy
INFO: --> In populateRandomCars for TableBeanLazy
INFO: --> In constructor for TableBeanLazy
INFO: --> In initialise for TableBeanLazy
INFO: --> In populateRandomCars for TableBeanLazy
INFO: --> In constructor for TableBeanLazy
INFO: --> In initialise for TableBeanLazy
INFO: --> In populateRandomCars for TableBeanLazy
单击搜索图标时的输出
INFO: --> In constructor for TableBeanLazy
INFO: --> In initialise for TableBeanLazy
INFO: --> In populateRandomCars for TableBeanLazy
INFO: --> In constructor for TableBeanLazy
INFO: --> In initialise for TableBeanLazy
INFO: --> In populateRandomCars for TableBeanLazy
INFO: --> In constructor for TableBeanLazy
INFO: --> In initialise for TableBeanLazy
INFO: --> In populateRandomCars for TableBeanLazy
INFO: --> In constructor for TableBeanLazy
INFO: --> In initialise for TableBeanLazy
INFO: --> In populateRandomCars for TableBeanLazy
INFO: java.lang.ArithmeticException: / by zero
java.lang.ArithmeticException: / by zero
at org.primefaces.model.LazyDataModel.setRowIndex(LazyDataModel.java:62)
at org.primefaces.component.api.UIData.setRowModel(UIData.java:409)
at org.primefaces.component.api.UIData.setRowIndex(UIData.java:401)
at org.primefaces.component.api.UIData.processChildren(UIData.java:289)
at org.primefaces.component.api.UIData.processPhase(UIData.java:261)
at org.primefaces.component.api.UIData.processDecodes(UIData.java:227)
at com.sun.faces.context.PartialViewContextImpl$PhaseAwareVisitCallback.visit(PartialViewContextImpl.java:506)
at com.sun.faces.component.visit.PartialVisitContext.invokeVisitCallback(PartialVisitContext.java:183)
at org.primefaces.component.api.UIData.visitTree(UIData.java:639)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
at javax.faces.component.UIForm.visitTree(UIForm.java:344)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
at com.sun.faces.context.PartialViewContextImpl.processComponents(PartialViewContextImpl.java:376)
at com.sun.faces.context.PartialViewContextImpl.processPartial(PartialViewContextImpl.java:252)
at javax.faces.context.PartialViewContextWrapper.processPartial(PartialViewContextWrapper.java:183)
at javax.faces.component.UIViewRoot.processDecodes(UIViewRoot.java:931)
at com.sun.faces.lifecycle.ApplyRequestValuesPhase.execute(ApplyRequestValuesPhase.java:78)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1550)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195)
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860)
at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757)
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056)
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229)
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
at java.lang.Thread.run(Thread.java:722)
INFO: --> In constructor for TableBeanLazy
INFO: --> In initialise for TableBeanLazy
INFO: --> In populateRandomCars for TableBeanLazy
INFO: --> In constructor for TableBeanLazy
INFO: --> In initialise for TableBeanLazy
INFO: --> In populateRandomCars for TableBeanLazy
INFO: --> In constructor for TableBeanLazy
INFO: --> In initialise for TableBeanLazy
INFO: --> In populateRandomCars for TableBeanLazy
INFO: java.lang.ArithmeticException: / by zero
java.lang.ArithmeticException: / by zero
at org.primefaces.model.LazyDataModel.setRowIndex(LazyDataModel.java:62)
at org.primefaces.component.api.UIData.setRowModel(UIData.java:409)
at org.primefaces.component.api.UIData.setRowIndex(UIData.java:401)
at org.primefaces.component.api.UIData.processChildren(UIData.java:289)
at org.primefaces.component.api.UIData.processPhase(UIData.java:261)
at org.primefaces.component.api.UIData.processValidators(UIData.java:241)
at com.sun.faces.context.PartialViewContextImpl$PhaseAwareVisitCallback.visit(PartialViewContextImpl.java:508)
at com.sun.faces.component.visit.PartialVisitContext.invokeVisitCallback(PartialVisitContext.java:183)
at org.primefaces.component.api.UIData.visitTree(UIData.java:639)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
at javax.faces.component.UIForm.visitTree(UIForm.java:344)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
at com.sun.faces.context.PartialViewContextImpl.processComponents(PartialViewContextImpl.java:376)
at com.sun.faces.context.PartialViewContextImpl.processPartial(PartialViewContextImpl.java:252)
at javax.faces.context.PartialViewContextWrapper.processPartial(PartialViewContextWrapper.java:183)
at javax.faces.component.UIViewRoot.processValidators(UIViewRoot.java:1170)
at com.sun.faces.lifecycle.ProcessValidationsPhase.execute(ProcessValidationsPhase.java:76)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1550)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195)
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860)
at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757)
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056)
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229)
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
at java.lang.Thread.run(Thread.java:722)
INFO: --> In constructor for TableBeanLazy
INFO: --> In initialise for TableBeanLazy
INFO: --> In populateRandomCars for TableBeanLazy
INFO: --> In constructor for TableBeanLazy
INFO: --> In initialise for TableBeanLazy
INFO: --> In populateRandomCars for TableBeanLazy
INFO: --> In constructor for TableBeanLazy
INFO: --> In initialise for TableBeanLazy
INFO: --> In populateRandomCars for TableBeanLazy
INFO: java.lang.ArithmeticException: / by zero
java.lang.ArithmeticException: / by zero
at org.primefaces.model.LazyDataModel.setRowIndex(LazyDataModel.java:62)
at org.primefaces.component.api.UIData.setRowModel(UIData.java:409)
at org.primefaces.component.api.UIData.setRowIndex(UIData.java:401)
at org.primefaces.component.api.UIData.processChildren(UIData.java:289)
at org.primefaces.component.api.UIData.processPhase(UIData.java:261)
at org.primefaces.component.api.UIData.processUpdates(UIData.java:253)
at org.primefaces.component.datatable.DataTable.processUpdates(DataTable.java:550)
at com.sun.faces.context.PartialViewContextImpl$PhaseAwareVisitCallback.visit(PartialViewContextImpl.java:510)
at com.sun.faces.component.visit.PartialVisitContext.invokeVisitCallback(PartialVisitContext.java:183)
at org.primefaces.component.api.UIData.visitTree(UIData.java:639)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
at javax.faces.component.UIForm.visitTree(UIForm.java:344)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
at com.sun.faces.context.PartialViewContextImpl.processComponents(PartialViewContextImpl.java:376)
at com.sun.faces.context.PartialViewContextImpl.processPartial(PartialViewContextImpl.java:252)
at javax.faces.context.PartialViewContextWrapper.processPartial(PartialViewContextWrapper.java:183)
at javax.faces.component.UIViewRoot.processUpdates(UIViewRoot.java:1229)
at com.sun.faces.lifecycle.UpdateModelValuesPhase.execute(UpdateModelValuesPhase.java:78)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1550)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195)
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860)
at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757)
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056)
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229)
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
at java.lang.Thread.run(Thread.java:722)
INFO: --> In constructor for TableBeanLazy
INFO: --> In initialise for TableBeanLazy
INFO: --> In populateRandomCars for TableBeanLazy
INFO: --> In constructor for TableBeanLazy
INFO: --> In initialise for TableBeanLazy
INFO: --> In populateRandomCars for TableBeanLazy
INFO: --> In constructor for TableBeanLazy
INFO: --> In initialise for TableBeanLazy
INFO: --> In populateRandomCars for TableBeanLazy
INFO: --> In constructor for TableBeanLazy
INFO: --> In initialise for TableBeanLazy
INFO: --> In populateRandomCars for TableBeanLazy
INFO: --> In constructor for TableBeanLazy
INFO: --> In initialise for TableBeanLazy
INFO: --> In populateRandomCars for TableBeanLazy