java - 为什么 JSF ManagedBean 方法要执行多次,而它们本来应该只执行一次?

标签 java jsf setter getter

在使用 JSF 来使用 NetBeans 开发 Web 应用程序时,我多次注意到,在某些情况下,JSF ManagedBeand 中的 getter 方法(可能还有 setter)在它们打算执行时会被执行多次只有一次。在这种情况下,有时对于某些操作(尤其是某些计算)强制执行一些关键条件(if等)以防止它们被淹没是极其重要的。我一直试图了解其背后的真正原因,但我无法做到。

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

public Collection<entity.Country> getCountries(){};

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

无需过多关注屏幕截图、JSF 页面代码及其相应的 ManagedBean。

All countries from MySql database.

这是 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;
    }

}

显示实际数据的数据表绑定(bind)到国家属性value="#{country.countries}" ManagedBean的相关内容及其对应的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 次,为什么......???

最佳答案

长话短说:Why JSF calls getters multiple times

在这种特殊情况下,您应该使用 @PostConstruct方法而不是预加载/初始化从注入(inject)的业务服务检索的内容,而不是 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.
}

关于java - 为什么 JSF ManagedBean 方法要执行多次,而它们本来应该只执行一次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7961475/

相关文章:

java - 如何在 Java 中使用 XPath 解析 XML

validation - 检查自定义验证器中的必填字段

java - 设置方法或构造函数

java - RequestDispatcher 转发正在重新路由回同一个 Servlet

java - 识别当前正在处理的元素

java - 避免在 h :inputText 中显示默认的 int 值 0

java - 如何处理 session 范围内的多选项卡数据

java - 使用 boolean 值设置实体的字符串字段?

objective-c - 在 iOS 上的 Objective-C 中,使用合成 getter 时 "self.foo"和 "foo"之间的(样式)区别是什么?

eclipse - 使用 Java; HashMap 和 ArrayList 无法在 Eclipse 或 BlueJay 中编译