经过一些实验,这在使用CDI bean时似乎是一个问题,与我最初假设的PrimeFaces无关。
如果我使用@ManagedBean将TableBeanLazy更改为Managed Bean,那么构造函数和@PostConstruct方法只会被调用一次,就像我期望的那样。
任何人都可以对此有所了解吗?
=============================================== ====
我是JSF和PrimeFaces的新手,所以任何指导都会非常感激。我搜索了其他帖子,并阅读了许多类似的帖子,但找不到解决方案。
我正在尝试在我的项目中使用PrimeFaces Showcase站点上的延迟加载数据表示例,但由于bean类的行为不像我期望的那样,我遇到了问题。
我对PrimeFaces站点的示例代码进行了一些更改: - 将TableBean类重命名为TableBeanLazy;在课堂上添加了注释;分配静态字符串数组;将初始化从构造函数移动到@PostConstruct initialise()方法;分配了 cars 成员变量。
我还在构造函数和@PostConstruct方法中添加了跟踪消息,这些消息显示在首次显示表时多次调用它们,每次单击搜索图标多次调用,并且每个字符多次调用在过滤器字段中输入。
这会导致每次执行操作时都会重新创建Car对象的随机列表,因此sort和filter将永远不会产生预期的结果 - 这是在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
答案 0 :(得分:9)
以下是您对CDI和JSF的第一条建议 - 永远不要将CDI与JSF注释混合。
您的问题是您使用@javax.inject.Named
CDI注释javax.faces.bean.SessionScoped
- JSF注释。
在CDI中你会这样做:
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
@Named(value = "tableBeanLazy")
@SessionScoped
public class TableBeanLazy {...}
请注意,上面的内容与JSF完全一致。
以纯JSF方式执行:
import javax.faces.bean.SessionScoped;
import javax.faces.bean.ManagedBean;
@ManagedBean(value = "tableBeanLazy")
@SessionScoped
public class TableBeanLazy {...}
我建议一直坚持使用CDI。但是,CDI目前没有提供开箱即用的JSF @javax.faces.bean.ViewScoped
的替代方案。要在CDI中获取它,请查看Apache Deltaspike。