为什么JSF ManagedBean方法只执行一次时执行了多次?

Bha*_*esh 0 java getter setter jsf

在使用JSF来开发使用NetBeans的Web应用程序时,我曾多次注意到在某些情况下,JSF ManagedBeand中的getter方法(以及可能的setter)也会被执行多次,而它们只打算执行一次.在这种情况下,有时执行某些操作(特别是某些计算)的某些关键条件(如果等)以防止它们被淹没是非常关键的.我一直在努力了解其背后的实际原因,但我不能.

在这里,我演示了一个非常简单的应用程序,其中有一个getter方法

public Collection<entity.Country> getCountries(){};
Run Code Online (Sandbox Code Playgroud)

调用远程EJB并从MySql数据库中的相关表中检索所有国家/地区并在JSF页面上显示.网页的屏幕截图如下所示.

没有必要对屏幕截图,JSF页面代码及其相应的ManagedBean付出太多和特别的关注.

来自MySql数据库的所有国家.

这是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>
Run Code Online (Sandbox Code Playgroud)

相应的简单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;
    }

}
Run Code Online (Sandbox Code Playgroud)

显示实际数据的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;
}
Run Code Online (Sandbox Code Playgroud)

该方法countries=obj.getAllCountries();从远程EJB检索数据.我觉得在这里发布这个方法的实际实现(在EJB中)是非常不必要的.所有这些只是为了展示我正在努力的目标.

现在,我的实际问题是public Collection<entity.Country> getCountries(){}不必要地执行8次,而它必须只执行一次,这在某些特定情况下非常关键.

我已经尝试了这么多次,同时增加和减少显示的行数仍然这个方法总是执行8次,为什么...... ???

Bal*_*usC 6

长话短说:为什么JSF多次调用getter

在这种特殊情况下,您应该使用@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.
}
Run Code Online (Sandbox Code Playgroud)