Почему методы JSF ManagedBean выполняются более одного раза, в то время как они предназначены для выполнения только один раз? - PullRequest
0 голосов
/ 01 ноября 2011

Работая с JSF для разработки веб-приложений с использованием NetBeans, я много раз замечал, что при некоторых обстоятельствах методы получения (и, возможно, также и установки) в JSF ManagedBeand выполняются более одного раза, пока они предназначены для выполнения. только однажды. В таком сценарии иногда крайне важно обеспечить выполнение некоторых критических условий (если и т. Д.) Для некоторых операций (особенно некоторых вычислений), чтобы предотвратить их перегрузку. Я продолжал пытаться узнать истинную причину этого, но я не мог.

Здесь я демонстрирую очень простое приложение, в котором метод получения, а именно

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

}

Таблица данных, в которой отображаются фактические данные, привязана к свойству страны value="#{country.countries}" объекта ManagedBean, и его соответствующие методы получения и установки имеют следующий вид.

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 раз, почему ... ???

1 Ответ

6 голосов
/ 01 ноября 2011

Короче говоря: Почему JSF вызывает геттеры несколько раз

В этом конкретном случае вы должны использовать метод @PostConstruct вместо предварительной загрузки / инициализацииматериал, извлеченный из внедренной бизнес-службы, а не метод получения.

@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.
}
...