在使用JSF开发Web应用程序时,我曾多次注意到在某些情况下,JSF ManagedBeand中的getter方法(也可能是setter)在执行它们时会被执行多次只有一次。在这种情况下, 有时 对于某些操作(尤其是某些计算)强制执行某些关键条件(如果等)非常重要,以防止它们被淹没。我一直在努力了解其背后的实际原因,但我不能。
在这里,我演示了一个非常简单的应用程序,其中有一个getter方法,即
public Collection<entity.Country> getCountries(){};
调用远程 EJB 并从MySql数据库中的相关表中检索所有国家/地区并在JSF页面上显示。网页的屏幕截图如下所示。
没有必要特别注意屏幕截图,JSF页面代码及其对应的ManagedBean。
这是JSF页面代码
<?xml version='1.0' encoding='UTF-8' ?>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>Countries</title>
</h:head>
<h:body>
<h:form>
<center><br/><br/><br/>
<h:dataTable id="dataTable" styleClass="table" frame="box" value="#
{country.countries}" var="row" bgcolor="lightyellow" border="7"
cellpadding="7" cellspacing="7" rules="all" width="50%" dir="ltr">
<f:facet id="header" name="header">
<h:outputText value="~:Country:~" styleClass="tableHeader"/>
</f:facet>
<h:column>
<f:facet name="header">Country ID</f:facet>
<h:outputText id="countryID" value="#{row.countryID}"/>
</h:column>
<h:column>
<f:facet name="header">Country Name :</f:facet>
<h:outputText id="countryName" value="#{row.countryName}"/>
</h:column>
</h:dataTable>
</center>
</h:form>
</h:body>
</html>
和相应的简单JSF ManagedBean代码在这里。
package country;
import commonBean.CommomBeanRemote;
import java.util.Collection;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
@ManagedBean
@RequestScoped
public class Country
{
@EJB
private CommomBeanRemote obj=null;
private Collection<entity.Country>countries=null;
public Country() {}
public Collection<entity.Country> getCountries()
{
countries=obj.getAllCountries(); //Calls a remote EJB to retrieve the data.
System.out.println("The Country() method called.");//Here this displays 8 times unnecessarily
return countries;
}
public void setCountries(Collection<entity.Country> countries)
{
this.countries = countries;
}
}
显示实际数据的dataTable绑定到ManagedBean的 countries 属性value="#{country.countries}"
,它的相应getter和setter如下所示。
public Collection<entity.Country> getCountries()
{
countries=obj.getAllCountries();
System.out.println("The Country() method called.");
return countries;
}
public void setCountries(Collection<entity.Country> countries)
{
this.countries = countries;
}
方法countries=obj.getAllCountries();
从远程 EJB 检索数据。 我觉得在这里发布这个方法的实际实现(在EJB中)是非常不必要的。所有这些只是为了展示我正在尝试的东西。
现在,我的实际问题是public Collection<entity.Country> getCountries(){}
被不必要地执行8次,而它必须只执行一次,这在某些特定情况下非常关键。
我已经尝试了这么多次,同时增加和减少显示的行数仍然这个方法总是执行8次,为什么...... ???
答案 0 :(得分:6)
长话短说:Why JSF calls getters multiple times
在这种特殊情况下,您应该使用@PostConstruct
方法来预加载/初始化从注入的业务服务检索的内容,而不是getter方法。
@ManagedBean
@RequestScoped
public class Country {
@EJB
private CommomBeanRemote commonBeanRemote;
private Collection<entity.Country> countries;
@PostConstruct
public void init() {
countries = commonBeanRemote.getAllCountries();
}
public Collection<entity.Country> getCountries() {
return countries;
}
// Setter is completely unnecessary here.
}