Artigo no estilo: Curso

Por que eu devo ler este artigo:No terceiro artigo da série será desenvolvida toda a interface gráfica do sistema para gerenciamento de bibliotecas. Para isso, aprenderemos a criar as páginas utilizando os principais componentes do JSF e a associá-los a propriedades de um managed bean.

Explicaremos também o que é um managed bean, qual sua relação com a anotação @Named, do CDI, e porque usar @Named em vez de @ManagedBean.

Ainda nesse artigo, durante o desenvolvimento da aplicação, passaremos pela API do JSF mostrando de forma prática como utilizar em conjunto as classes FacesContext e NavigationHandler para navegar entre as views.

Portanto, tal conteúdo é de grande valia para os leitores que desejam aprender mais sobre uma das principais tecnologias do Java: o JavaServer Faces.

Ao longo desta série de artigos estamos desenvolvendo uma aplicação web que possibilita o gerenciamento de bibliotecas. Até o presente momento já criamos o projeto no Eclipse, configuramos o arquivo persistence.xml, realizamos o mapeamento de nossas entidades, implementamos o DAO e uma classe para gerenciar as transações. No entanto, o cliente ainda não consegue interagir com o sistema, pois ainda não criamos as páginas que irão conter a parte da interface gráfica.

Sendo assim, a partir de agora vamos desenvolver as principais páginas desta aplicação. São elas:

· _template_simples.xhtml e _template.xhtml – que representam os arquivos de template (veremos mais detalhes sobre eles adiante);

· login.xhtml – página para que o usuário do sistema possa se autenticar;

· principal.xhtml – página que contém os links que dão acesso às outras partes do sistema;

· funcionário_biblioteca.xhtml – página que permite que sejam cadastrados dados relacionados aos novos funcionários da biblioteca e um usuário e senha para cada um deles;

· emprestimo.xhtml – página que possibilita o empréstimo de livros;

· devolucao.xhtml – página para que se possa realizar a devolução dos livros emprestados.

Estas páginas irão conter os componentes visuais que compõem a interface gráfica da nossa aplicação. A camada de visão (que será composta por tais páginas) ficará separada das demais camadas pelo fato de o JSF ser um framework MVC.

Ademais, como existe essa separação de responsabilidades, a lógica de negócios deve ficar dentro dos managed beans. Em suma, a ideia central é que as páginas trabalhem em conjunto com os managed beans – que contêm o código Java com a lógica de negócio.

Dito isso, daremos sequência ao desenvolvimento do nosso sistema, criando as páginas JSF, os managed beans e algumas outras classes relativas à navegação.

Criando as páginas JSF e os Managed Beans

Com as entidades e as classes DAO prontas, iremos iniciar o desenvolvimento das páginas JSF e dos managed beans. Nossas páginas irão utilizar imagens e um arquivo .css para formatação.

Estes arquivos (que podem ser baixados do projeto exemplo disponível no GitHub) devem ser colocados na pasta resources, que precisa ser criada dentro da pasta WebContent do projeto. Por estar fora do escopo deste artigo, não exibiremos o conteúdo do arquivo CSS.

Templates

Uma boa prática que devemos adotar durante o desenvolvimento de um sistema é evitar a duplicidade de código e isso também vale para nossas páginas. Uma maneira de evitarmos isso é criando arquivos de template com a biblioteca de tags Facelets.

Um arquivo de template deve agrupar os códigos que são comuns a várias páginas. No caso da nossa aplicação, os templates definirão o cabeçalho e o rodapé, pois são coisas comuns a todas as páginas.

Fazendo uma analogia, imagine um template como se fosse uma folha de papel com buracos, e esses buracos são locais onde podemos encaixar diversos conteúdos diferentes. Assim, cada cliente do template (template client), no caso a página que usa o template, poderia inserir um conteúdo diferente em cada um desses “buracos”.

Criaremos dentro de WEB-INF dois arquivos de template: um chamado _template_simples.xhtml e outro chamado _template.xhtml. Mantê-los dentro de WEB-INF é uma forma de evitar que sejam acessados diretamente pelo navegador através de uma URL.

A Listagem 1 mostra o conteúdo da página _template_simples.xhtml. Para que as tags do Facelets funcionem nessa página, precisamos declarar o namespace xmlns:ui="http://java.sun.com/jsf/facelets, o que é feito logo no início do arquivo. Repare que em meio ao código dessa listagem encontramos a tag ui:insert, que faz parte da biblioteca Facelets.

O prefixo ui é o que sinaliza que essa tag pertence a tal biblioteca. Note que ui é o mesmo valor utilizado na declaração do namespace. O propósito de ui:insert é demarcar as partes do template que podem ser substituídas pelas páginas clientes que irão usar esse template.

Seguindo com a análise do código, podemos observar que o corpo dessa página possui quatro divs: a primeira representa o cabeçalho e contém uma imagem; a segunda mostra o usuário logado e tem um botão para fazer logout; a terceira é reservada para comportar o conteúdo principal da página (é a que contém a tag ui:insert); e a quarta e última div representa o rodapé.

Na div com id usuarioLogado o managed bean usuarioLogadoBean (veremos seu código adiante) é utilizado para exibir o nome do usuário logado caso algum já tenha se autenticado.

A outra página de template, template.xhtml, que veremos a seguir, tem basicamente a mesma estrutura, contendo apenas algumas tags a mais dentro da div do conteúdo.

Como todas as outras páginas serão clientes ou da página _template_simples.xhtml ou da página _template.xhtml, terão por consequência essa estrutura também e irão apenas substituir o conteúdo principal.

Listagem 1. Código do arquivo _template_simples.xhtml.


  <?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:f="http://java.sun.com/jsf/core"
          xmlns:h="http://java.sun.com/jsf/html"
          xmlns:ui="http://java.sun.com/jsf/facelets">
   
  <h:head>
        <title>Easy - Sistema Gerenciador de Biblioteca</title>
        <h:outputStylesheet library="css" name="style.css"/>
  </h:head>
   
  <h:body>
        <div id="cabecalho">
              <h:graphicImage library="imagens" name="logo-easy.png" id="logoCompany"/>
        </div>
        
        <div id="usuarioLogado">
              <h:form rendered="#{usuarioLogadoBean.logado}">
                     Logado como: #{usuarioLogadoBean.usuario.usuario}
                     <h:commandButton value="[Sair]" action="#{loginBean.efetuarLogout}" />
              </h:form>
        </div>
        
        <div id="conteudo">
              <ui:insert name="corpo" />
        </div>
        
        <div id="rodape">
              Copyright 2014.
              Todos os Direitos reservados a Easy Java Magazine
        </div>
  </h:body>
  </html>

Listagem 2. Código do arquivo _template.xhtml.


  <!-- restante do código ... -->
  <div id="conteudo">       
        <br/>  
        <h:form>
              <h:messages globalOnly="true" showDetail="true" />
        </h:form>    
        <br/>
        <ui:insert name="corpo" /> 
        <h:form>
               <h:commandLink value="Voltar ao Menu" action="principal?faces-redirect=true" />
        </h:form>
              
  </div>
  <!-- restante do código ... -->

Como mencionado anteriormente, o conteúdo do arquivo _template.xhtml é quase igual ao do arquivo _template_simples.xhtml. Devido a isso, na Listagem 2 é mostrada somente a parte diferente entre os dois para evitar listagens com código duplicado.

O que muda entre os dois é o que está presente dentro da div conteudo. Nesse local, no arquivo _template.xhtml, usamos a tag h:messages para mostrar ao usuário as mensagens que forem adicionadas através do método addMessage() da classe FacesContext.

Logo abaixo é usada a tag ui:insert, que já foi explicada. Por último, através da tag h:commandLink é criado um link que aponta para o menu principal, que é apenas uma página que contém os links para as demais.

Lembre-se que a tag h:commandLink precisa estar dentro de h:form para funcionar.

Autenticação

Antes de criarmos a página de login e o managed bean associado a ela para que o usuário possa se autenticar, precisamos criar outros managed beans que irão apoiar esse processo de autenticação.

Listagem 3. Código do managed bean UsuarioLogadoBean.


  package br.com.javamagazine.mb;
   
  import java.io.Serializable;
  import javax.enterprise.context.SessionScoped;
  import javax.inject.Named;
  import br.com.javamagazine.entidades.Usuario;
   
  @Named
  @SessionScoped
  public class UsuarioLogadoBean implements Serializable{
   
        private static final long serialVersionUID = 1L;
        private Usuario usuario;
        
        public void logar(Usuario usuario){
              this.usuario = usuario;
        }
        
        public void deslogar(){
              this.usuario = null;
        }
        
        public boolean isLogado(){
              return usuario != null;
        }
        
        public Usuario getUsuario(){
              return usuario;
        }
  }

O código do primeiro managed bean que apresentamos neste artigo se encontra na Listagem 3, UsuarioLogadoBean. Um managed bean pode ser definido como um objeto que é gerenciado pelo container.

Se estivéssemos usando JSF sem CDI, poderíamos adotar a anotação @ManagedBean(javax.faces.bean.ManagedBean) para registrar a classe como um managed bean do JSF.

Porém, a recomendação é que se use managed beans gerenciados pelo container CDI e não pelo JSF, e por isso é preferível usar a anotação @Named no lugar de @ManagedBean.

Na própria especificação do JavaServer Faces 2.2 (JSR-344) é dito que as anotações do pacote javax.faces.bean serão depreciadas (deprecated) em futuras versões.

Além disso, os managed beans do CDI são mais poderosos e flexíveis. Com eles podemos fazer uso de interceptors, escopo conversacional, eventos, injeção de dependências type safe, decorators, stereotypes e métodos produtores (que usam @Produces).

É importante ressaltar que a anotação @Named não torna a classe um bean. Ela apenas possibilita referenciarmos esse bean dentro de uma EL presente em alguma página JSF. O container CDI trata qualquer classe que satisfaça as condições a seguir como um managed bean:

· Que não seja uma classe interna não estática (non-static inner class);

· Que seja uma classe concreta ou “anotada” com @Decorator;

· Que não esteja “anotada” com qualquer anotação que a defina como um EJB ou declarada como um EJB no arquivo ejb-jar.xml;

· Que não implemente javax.enterprise.inject.spi.Extension;

· Que tenha um construtor apropriado, que pode ser um construtor default sem parâmetros ou um construtor marcado com @Inject.

A anotação @Named nos permite dar um nome a nosso bean, pois ela aceita uma String como argumento, e esse é o nome que deve ser usado dentro de qualquer EL que queira utilizar esse bean.

Por exemplo, poderíamos colocar em cima da classe UsuarioLogadoBean a anotação @Named(“usuarioBean”). Assim, na EL usaríamos esse nome: #{usuarioBean.logado}. Também existe a opção de não passarmos nenhuma String para a anotação, escrevendo apenas @Named.

Nesse caso, será usado o nome padrão, que é o nome não qualificado da classe com a primeira letra em minúsculo. Para a classe UsuarioLogadoBean, o nome padrão seria usuarioLogadoBean.

Na classe UsuarioLogadoBean foram colocadas as anotações @Named e @SessionScoped. Esta última indica que só existirá uma instância desse bean por sessão.

Esse bean irá armazenar o objeto usuario que representa o usuário logado no sistema. É uma classe bem simples que contém apenas quatro métodos: o logar(), que seta o usuário logado na variável usuario; o deslogar(), que seta a variável usuario como nula; o isLogado(), que retorna um boolean para indicar se existe algum usuário logado; e o getUsuario(), que retorna o usuário logado.

Listagem 4. Código do managed bean FuncionarioEUsuarioVerificadorBean.


  package br.com.javamagazine.mb;
   
  import javax.enterprise.context.RequestScoped;
  import javax.inject.Inject;
  import javax.inject.Named;
   
  import br.com.javamagazine.dao.FuncionarioBibliotecaDao;
  import br.com.javamagazine.dao.UsuarioDao;
   
  @Named
  @RequestSc ... 

Quer ler esse conteúdo completo? Tenha acesso completo