Arquivo

Posts Tagged ‘@SessionScoped’

Introdução ao JSF 2.0 com PrimeFaces parte II

Hoje eu vou mostrar mais um componente do primefaces e vou também falar um pouco sobre a nova forma de declarar Managed Beans no JSF 2.0. O componente que vou mostrar é o <p:collector />, esse componente é um facilitador para formulario do tipo  mestre-detalhe visto que ele inseri e remove objetos de uma lista a ele associado. O componente comumente está associado á um componente <h:commandButton> e um <h:dataTable />.

Criando nossas classes de Modelo e Managed Bean.

Seguindo o exemplo que foi dado no último post, a nossa estrutura de projeto deve está conforme a imagem exibida abaixo:

Estrutura do projeto

Por questão de organização e padronização nós vamos adicionar dois novos pacotes em nosso pacotes de código-fonte chamados de org.seed.exemploprime.managedbeans e org.seed.exemploprime.modelo. Para criar os pacotes basta clicar com o botão direito sobre a pasta Pacotes de código-fonte –> Novo –> Pacote Java. Dentro do pacote org.seed.exemploprime.modelo vamos adicionar uma classe java chamada de Aluno, a classe Aluno representa uma entidade de nosso sistema e é comumente chamada pela comunidade como um DTO (Data Transfer Object) e segue um padrão chamado de JavaBeans. A nossa classe é exibida abaixo:

package org.seed.exemploprime.modelo;

/**
 *criado em 27/04/2010
 * @author wagnerborges
 */
public class Aluno {
 private String matricula;
 private String nomeCompleto;
 private String login;
 private String senha;

 public String getLogin() {
 return login;
 }

 public void setLogin(String login) {
 this.login = login;
 }

 public String getMatricula() {
 return matricula;
 }

 public void setMatricula(String matricula) {
 this.matricula = matricula;
 }

 public String getNomeCompleto() {
 return nomeCompleto;
 }

 public void setNomeCompleto(String nomeCompleto) {
 this.nomeCompleto = nomeCompleto;
 }

 public String getSenha() {
 return senha;
 }

 public void setSenha(String senha) {
 this.senha = senha;
 }
}

Agora vamos adicionar no pacote org.seed.exemploprime.managedbeans uma classe chamada de AlunoManagedBean, essa classe vai interagir com nossa página capturando os eventos e dados fornecidos pelos usuários. Essa classe também é chamada de Backing Bean. A classe vai ficar como o código abaixo:


package org.seed.exemploprime.managedbeans;

import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ManagedBean;
import org.seed.exemploprime.modelo.Aluno;

/**
 *criado em 27/04/2010
 * @author wagnerborges
 */

@ManagedBean
@SessionScoped

public class AlunoManagedBean {
 private Aluno aluno = new Aluno();
 private List<Aluno> listaAlunos = new ArrayList();

 public Aluno getAluno() {
 return aluno;
 }

 public void setAluno(Aluno aluno) {
 this.aluno = aluno;
 }

 public List<Aluno> getListaAlunos() {
 return listaAlunos;
 }

 public void setListaAlunos(List<Aluno> listaAlunos) {
 this.listaAlunos = listaAlunos;
 }

public void create(){
 aluno = new Aluno();
 }


}

A classe acima merece alguns comentários. Como foi dito acima ela representa um managed bean, isso significa dizer que eu posso vincular (binding) seus atributos ou métodos com componentes de minhas páginas JSF. É essa caracteristica que torna o JSF uma framework orientado a componentes e a eventos. O que caractetiza nossa classe como sendo um bean gerenciado é a anotação @ManagedBean sobre a definição da classe. Essa é nova forma de se declarar  Managed Bean na nova especificação JSF, antes isso era feito em pelo menos 5 linhas em um arquivo xml chamdo de faces-config.xml que é o arquivo de configuração do Java Server Faces. Uma outra anotação que podemos perceber logo abaixo é a anotação @SessionScoped, essa anotação informa que o escopo de nosso bean gerenciado é de sessão, ou seja, enquanto durar minha sessão eu vou ter um objeto da classe AlunoManagedBean na sessão da minha aplicação. Análogo ao escopo de sessão existe o escopo de request referenciado pela anotação @RequestScoped onde um novo objeto é criado a cada requisição realizada pelo usuario. Ainda existem outros tipos de escopos: @ConversationScoped que cria um escopo de conversação entre duas páginas onde os objetos permanecem “vivos”  entre a pagina que originou o request até a página alvo. @ApplicationScoped que cria um escopo cujos os objetos são vistos por toda aplicação enquanto a aplicação estiver em execução.

Nossa classe AlunoManagedBean possui dois atributos: aluno da classe Aluno cujos atributos vamos vincular com os campos do nosso formulario e um atributo listaAlunos que é do tipo ArrayList que é onde vamos armazenar nossos objetos criado. A lista também será usada para exibir uma tabela com os objetos já cadastrados. Além dos dois atributos a classe possui um método chamado de create que será chamdo sempre que um novo objeto for inserido na lista, isso para que todos objetos sejam diferentes e não apontem para o mesmo endereço de memória.

Feito isso, a nova estrutura de nosso projeto deve está conforme imagem abaixo:

Nova Estrutura

O que vamos fazer agora é vincular nossa página index.xhtml com os atributos do nosso Bean Managed, mas qual é o nome do nosso Bean Managed? é o mesmo nome da classe? Antes do JSF2 deveriamos informa qual o nome do objeto que seria criado e referenciado nas páginas, mas agora quando colocamos a anotação @ManagedBean temos a opção de informa um nome ou não. Se desejarmos informar um nome fazemos assim: @ManagedBean(name=”alunoBean”), mas se não desejamos explicitar um nome para o nosso bean gerenciado um nome é criado tomando como base o nome da classe com a primeira letra em minusculo, então no nosso caso o objeto que será criado e que vamos referenciar em nossas páginas vai ser alunoManagedBean. Abaixo o código da nossa página index.html depois de alterado. Os comentários sobre os componentes vem logo em seguida.


<?xml version='1.0' encoding='UTF-8' ?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"

xmlns:h="http://java.sun.com/jsf/html"

xmlns:p="http://primefaces.prime.com.tr/ui"

xmlns:f="http://java.sun.com/jsf/core">

<h:head>

<title>Facelet Title</title>

</h:head>

<h:body>

<h:panelGrid>

<p:messages />

<h:form>

<p:panel closable="true" footer="Cadastro" header="Cadastro de Alunos" style="width: 350PX">

<h:panelGrid columns="2">

<h:outputLabel value="Matricula:"/>

<h:inputText id="matricula" required="true" value="#{alunoManagedBean.aluno.matricula}"

requiredMessage="Campo [Matricula] obrigatório"/>

<h:outputLabel value="Nome Completo:"/>

<h:inputText id="nome" required="true" value="#{alunoManagedBean.aluno.nomeCompleto}"

requiredMessage="Campo [Nome Completo] obrigatório"/>

<h:outputLabel value="Nome p/ Login:"/>

<h:inputText id="login" required="true" value="#{alunoManagedBean.aluno.login}"

requiredMessage="Campo [Nome p/ login] obrigatório"/>

<h:outputLabel value="Senha:"/>

<p:password minLength="6" value="#{alunoManagedBean.aluno.senha}"

promptLabel="Digite uma senha segura"

goodLabel="Boa"

weakLabel="Razoável"

strongLabel="Excelente" />

<h:commandButton value="Cadastrar" action="#{alunoManagedBean.create}">

<p:collector value="#{alunoManagedBean.aluno}" addTo="#{alunoManagedBean.listaAlunos}"/>

</h:commandButton>

</h:panelGrid>

</p:panel>

</h:form>

<br/><br/>

<h:form>

<p:dataTable value="#{alunoManagedBean.listaAlunos}" var="aluno">

<p:column>

<f:facet name="header">

<h:outputText value="Matricula" />

</f:facet>

<h:outputText value="#{aluno.matricula}" />

</p:column>

<p:column>

<f:facet name="header">

<h:outputText value="Nome" />

</f:facet>

<h:outputText value="#{aluno.nomeCompleto}" />

</p:column>

<p:column>

<f:facet name="header">

<h:outputText value="Login" />

</f:facet>

<h:outputText value="#{aluno.login}" />

</p:column>

<p:column>

<f:facet name="header">

<h:outputText value="Remover" />

</f:facet>

<h:commandLink value="remover">

<p:collector value="#{aluno}" removeFrom="#{alunoManagedBean.listaAlunos}"/>

</h:commandLink>

</p:column>

</p:dataTable>

</h:form>

</h:panelGrid>

</h:body>

</html>

Vamos aos comentários

Primeiramente, fazemos a vinculação dos campos com os atributos:

<pre><h:inputText id="matricula" required="true" value="#{alunoManagedBean.aluno.matricula}" requiredMessage="Campo [Matricula] obrigatório"/></pre>

alunoManagedBean é o nome do objeto que foi criado da nossa classe AlunoManagedBean, aluno é um atributo da classe Aluno e nomeCompleto um atributo do objeto aluno.

O trecho abaixo mostra onde fazemos uso do componente <p:collector /> associado com um componente <h:commandButton />, o componente <h:commanButton/> possui um atributo chamado de action onde informamos qual o método que deverá ser executado quando o mesmo for pressionado. Nesse caso, a action associada a esse botão é o método create do nosso ManagedBean. Em seguida nosso componente <p:collector/> é adicionado com dois atributos, no atributo value é informado qual o objeto do ManagedBean se deseja armazenar na lista e no atributo addTo é informado em qual lista o objeto será amazeado.

<pre><h:commandButton value="Cadastrar" action="#{alunoManagedBean.create}">

<p:collector value="#{alunoManagedBean.aluno}" addTo="#{alunoManagedBean.listaAlunos}"/>

</h:commandButton></pre>

Em seguida criamos uma tabela informando no atributo value qual a lista que será exibida e um atributo var para informa o nome do objeto que está sendo interado pela lista.

<pre><p:dataTable value="#{alunoManagedBean.listaAlunos}" var="aluno"></pre>

Na tabela também adicionamos um link para remover objetos da lista utilizando o componente <p:collector> informando qual o objeto se deseja remover através do atributo value e de qual lista esse objeto será removido através do atributo removeFrom.

<pre><h:commandLink value="remover">

<p:collector value="#{aluno}" removeFrom="#{alunoManagedBean.listaAlunos}"/>

</h:commandLink></pre>

A imagem abaixo exibe nossa página index.xhtml em execução:

Resultado Final do Exemplo

Bom pessoal é isso aí. Espero que gostem e que seja útil.

abraços e até a próxima.