Backing beans - why?

6 respostas
lblanco

Seguinte galera. Dúvido que alguém me explica isso !! rs

1 Tenho dois manager-bean: asController e geController

2 Dentro do geController tenho um metodo que seta um List e esse list é usado em um dataTable de um JSP

3 Dentro do meu asController eu instancio o meu geController e chamo o metodo que deveria setar o list

4 Em seguida vou para a pagina JSP que usa o list e ela está vazia :frowning:

Isso deveria funcionar ?
Quando eu chamo o geController de um JSP ele funciona normalmente.

Why ?

6 Respostas

Alexandre_Bitencourt

Bom dia,

Coloque seu faces-config.xml e a parte do código onde você está instanciando o geController pra eu poder ver o que pode estar acontecendo.

A maneira correta de você utilizar um bean dentro de outro é utilizar injeção de dependências através de managed properties conforme o exemplo abaixo:

...
<!-- Declara o bean geController que será injetado no asController -->
<managed-bean>
	<managed-bean-name>
		geController
	</managed-bean-name>
	<managed-bean-class>
		br.com.pacote.GEController
	</managed-bean-class>
	<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
<!-- Declaração do asController que terá o geController injetado -->
<managed-bean>
	<managed-bean-name>
		asController
	</managed-bean-name>
	<managed-bean-class>
		br.com.pacote.ASController
	</managed-bean-class>
        <!-- Faz a injeção de dependência atribuindo ao atributo geController do bean de nome geController -->
	<managed-property>
		<property-name>geController</property-name>
		<value>#{geController}</value>
	</managed-property>
	<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
...

Além disso observe o escopo dos managed beans, se algum deles for declarado com escopo request ou none a cada requisição o bean é recriado e os dados da lista são perdidos.

Espero ter ajudado,

Alexandre Fidélis Vieira Bitencourt

lblanco

Olá Alexandre, muito obrigado pela atenção.
Segue abaixo o meu faces-config:

<managed-bean>
        <managed-bean-name>asController</managed-bean-name>
        <managed-bean-class>websis.controller.as.asController</managed-bean-class>
        <managed-bean-scope>session</managed-bean-scope>
    </managed-bean>
    <managed-bean>
        <managed-bean-name>geController</managed-bean-name>
        <managed-bean-class>websis.controller.ge.geController</managed-bean-class>
        <managed-bean-scope>session</managed-bean-scope>
    </managed-bean>

Logo abaixo está o geController

public class geController {
  
    private gePais        gePaisCtr;
    private List             gePaisList;
    

    /*Metodo responsavel por efetuar a busca na tabela de pessoa*/
    public String gePaisSearchAll() {
        try {

            gePaisDAO gePaisDAO = new gePaisDAO();
            this.setGePaisList(gePaisDAO.searchAll());

            return "gePaisSearchAllSucess";

        } catch (Exception ex) {
            ex.printStackTrace();
            return "gePaisSearchAllError";
        }
    }

    /*Gets e Sets*/

}

Agora eu tenho o meu asController e gostaria de chamar de dentro dele o gePaisSearchAll que está em outro
manager bean: Abaixo a minha tentativa:

public class asController {
  
  private asMenu                  asMenuCtr;
  private List                        asMenuList;

  public String callOper(){

        com.pacote.web.geController ge = new com.pacote.web.geController();
        ge.gePaisSearchAll();
        return "x";
  }
  
  
 /*gets e sets*/
}

Diante disso com farei a tal injeção de dependências ?
Obrigado mais uma vez pela sua atenção.

Alexandre_Bitencourt

Vamos lá,

Sua tentativa não está funcionando por que ao criar um novo geControler você não está referenciando o managed bean que foi criado para a sessão do usuário. Ao invés disso você está criando uma nova instância da classe que não é a mesma que está na sessão do usuário.

Para acessar o managed bean geController que está na sessão do usuário a partir do bean asController você vai ter que fazer o seguinte:

1o. Altere sua classe asController para conter uma referência para o geController.
2o. Altere a declaração do asController no seu faces-config.xml para que o geController da session seja injetado no asController usando a tag managed-property.

No final das contas seu código vai ficar parecido com isso:

faces-config.xml:

<managed-bean>  
         <managed-bean-name>asController</managed-bean-name>  
         <managed-bean-class>websis.controller.as.asController</managed-bean-class>  
         <managed-bean-scope>session</managed-bean-scope> 
         <managed-property>
               <property-name>ge</property-name>
               <value>#{geController}</value>
         <managed-property>
     </managed-bean>  
     <managed-bean>  
         <managed-bean-name>geController</managed-bean-name>  
         <managed-bean-class>websis.controller.ge.geController</managed-bean-class>  
         <managed-bean-scope>session</managed-bean-scope>  
     </managed-bean>

asController.java

public class asController {  
    private asMenu                  asMenuCtr;  
    private List                        asMenuList;

    // instância do geController que será injetada pelo container através
    // da managed-property
    private geController           ge;

    public String callOper(){
        // basta chamar o método pois o ge já foi injetado pelo container  
        ge.gePaisSearchAll();  
        return "x";  
    }  

    /*gets e sets*/  
}

O seu geController pode continuar do mesmo jeito.

Observe que ao definir uma managed property na declaração do bean asController foi utilizada uma el referenciando o bean geController que foi declarado abaixo. Ao criar o managed bean asController o container irá procurar o geController na session e apontar a referencia ge para ele. Sendo assim quando você for usar o método callOper, a variável ge estará apontando para o bean geController da session e o método chamado será o dele.

Acho q ficou bem explicado. Qualquer dúvida é soh falar. Procure referencias sobre utilização de managed-properties.

abração

Alexandre Fidélis Vieira Bitencourt

lblanco

Alexandre,

Não sei como te agradecer, realmente ficou muito bem explicado. Muito obrigado pela sua atenção.
Um abraço.

lblanco

Alexandre, meu velho, tudo bom ?

Com base no que voce me explicou eu consegui fazer a injeção de dependencia e consegui chamar um metodo do meu outro controlador. Agora falta pouco para conseguir chegar no resultado que eu estou esperando.

Veja se você já passou por isso ou sabe como resolver isso.

1 - Tenho o asController que já está configurado para fazer a injeção de dependência do geController. Então temos:
ESSE PRIMEIRO EXEMPLO ESTÁ FUNCIONANDO PERFEITAMENTE.

public class asController {

    /*Injeção de Dependências */
    private geController           geController;   

   /* Metodo responsalve por instanciar um list ESTATICO */
   public String callOper() {
      
       this.geController.gePaisSearchAll();
       return "sucesso";
   }


   /* gets e sets */
}

2 - Agora tenho o mesmo asController porém querendo chamar o metodo de forma dinamica e nao estatica.
E nessa hora ele não dá erro , mas também nao usa a injeção de dependencia. Como seria para chamar dinamicamente e usando o geController

public class asController {

    /*Injeção de Dependências */
    private geController           geController;   

   /* Metodo responsalve por instanciar um list DINAMICO*/
   public String callOper() {

       /*TENTATIVA - 1 Carrega a classe que esta cadastrada na operacao 
         Funciona.. mas como nao uso a injeção de dependencia a pagina nao carrega*/
        Class  classe   = Class.forName("websis.controller.ge.geController");  
        Object objeto   = classe.newInstance();
        Method metodo   = classe.getMethod("gePaisSearchAll");
        String desc     = (String) metodo.invoke(objeto);
        return "sucesso"
   
      
   }


   /* gets e sets */
}
rponte

Dá uma lida nesse post, vai te ajudar a entender melhor a comunicação em JSF,

Abraços e boa sorte.

Criado 5 de junho de 2008
Ultima resposta 8 de jun. de 2008
Respostas 6
Participantes 3