lign=baseline border=0>

Uma Aplicação Java EE Completa

Parte 2: Implementando a interface web com JSF

Entenda porque utilizamos JSF, seu funcionamento, os principais componentes e a integração com a camada de persistência implementada com JPA

Vamos prosseguir com a construção de uma aplicação crítica, utilizando algumas das mais comentadas e sólidas tecnologias para desenvolvimento de software Java: JPA, JSF, AJAX e EJB 3.

No artigo anterior discutimos os requisitos da aplicação (o quadro “Requisitos, modelo de dados e Persistência” resume o que foi definido e criado, e permite acompanhar este artigo de forma mais independente). Falamos também de algumas decisões de projeto que foram tomadas, incluindo escolhas de tecnologias de desenvolvimento (veja o quadro “Checklist”). Também tivemos a oportunidade de verificar as facilidades para operações de persistência e mapeamento objeto-relacional introduzidas pela JPA (Java Persistence API).

Neste artigo vamos desenvolver os componentes da camada de apresentação com interface web, usando JSF.

Decisões de projeto

Um grande atrativo da plataforma Java é a independência de fornecedores de soluções. No caso do desenvolvimento de aplicações web encontramos muitos caminhos de desenvolvimento. Vamos nos ater às possibilidades mais difundidas no mercado, as quais discutimos a seguir.

J2EE tradicional - Servlets e JSP

Desde a primeira versão do Java 2 Enterprise Edition (J2EE), os servlets e as páginas JSP estão presentes como componentes de desenvolvimento de camada de apresentação web. A combinação de servlets e JSP elevou o nível da discussão de construção de aplicações do simples modelo baseado fortemente em páginas dinâmicas (aplicações page-centric) para a adoção da arquitetura MVC (Model-View-Controller).

MVC é uma arquitetura de software inicialmente proposta para aplicações desktop e adaptada para aplicações web, que define uma divisão de responsabilidades entre os componentes de software, capaz de desacoplar a lógica de negócios dos componentes de interface gráfica.

O desenvolvimento de aplicações web MVC trouxe à tona outros design patterns (por exemplo: Front Controller e Dispatcher View) que colaboram com a separação de responsabilidade proposta por esta arquitetura. Ao considerar todos os patterns e boas práticas disponíveis para a construção de software web de alta qualidade, verificou-se que a programação baseada em servlets e JSPs poderia se beneficiar de frameworks MVC, a fim de agilizar e gerenciar melhor o desenvolvimento.

Apache Struts

O Struts oferece uma infra-estrutura de desenvolvimento web orientada pelos principais design patterns sugeridos para MVC. Este é o framework MVC mais difundido no mercado, e sua robustez e popularidade o tornam extremamente competitivo ao escolher entre tecnologias web.

Em sua segunda versão o Struts se fundiu com outro framework bastante conhecido, o WebWork (veja detalhes sobre o Struts 2 no artigo de capa da Edição 41).

Mesmo com as facilidades e sucesso do Struts, havia no mercado uma autêntica demanda por mais produtividade de desenvolvimento. E ainda havia espaço para uma especificação de padronização de frameworks MVC, analogamente ao que ocorreu recentemente com a especificação JPA para frameworks de persistência. Então, aparece a proposta do JavaServer Faces.

JavaServer Faces

O JavaServer Faces não é apenas mais um framework, é uma especificação de um modelo de programação baseado na arquitetura MVC. Esta especificação define um padrão para o desenvolvimento de aplicações com alta produtividade e componentização.

Quando pensamos em produtividade e componentização, logo pensamos em aplicações desktop desenvolvidas com ferramentas RAD (Rapid Application Development) como Visual Basic, Delphi, Oracle Forms e outros, com editores de telas totalmente visuais e facilidades como componentes de interfaces gráficas “data-aware”. Pois bem, o JavaServer Faces traz, para o mundo de desenvolvimento web em Java, o modelo de programação que fez muito sucesso na geração desktop/client-server de software corporativo. Veja mais no quadro “Conhecendo o JavaServer Faces”.

O que nos faz adotar esta tecnologia é a definição de um padrão que está sendo adotado em massa pelo mercado, e que possibilita a portabilidade do software desenvolvido entre soluções de diferentes fornecedores.

Como funciona uma aplicação web com JavaServer Faces ?

 Em uma aplicação web, em geral, as páginas precisam interagir de alguma forma com os componentes de negócio, e representar o estado desses componentes. Em uma aplicação web com JSF, utilizamos bibliotecas de tags para criar uma página, e a JSF Expression Language (EL) para estabelecer a comunicação entre as páginas e a camada de negócios. São usados também Managed Beans para expor os objetos de negócio à camada de apresentação – veja a Figura 1.

 

 

Figura 1. Elementos de uma aplicação JSF

Vamos explorar cada um desses elementos, que serão construídos em função dos componentes de negócio desenvolvidos na primeira parte desta série (o download referente a este artigo inclui todos os arquivos desta e da parte anterior).

Managed Beans

Um Managed Bean é uma classe simples – veja a Listagem 1 – que expõe objetos de negócios para a camada de apresentação. Esse bean é registrado e associado a um nome no arquivo de configuração do ambiente JSF: WEB-INF/faces-config.xml. A seguir vemos um trecho deste arquivo de configuração:

 

<managed-bean>

     <managed-bean-name>alunosMB</managed-bean-name>

     <managed-bean-class>jm.matriculas.jsf.AlunosMB

     </managed-bean-class>

     <managed-bean-scope>session</managed-bean-scope>

</managed-bean>

 

Repare que, através do elemento <managed-bean-scope>, é possível definir a duração da existência de uma instância de managed bean. Os valores possíveis de escopo são request (a instância é gerenciada durante uma requisição), session (a instância é gerenciada durante a validade de uma sessão do usuário no container web), ou application (a mesma instância é acessada por todos os usuários/sessões e existe enquanto a aplicação web estiver ativa no container).

O nome configurado no elemento <managed-bean-name> será utilizado nas expressões EL das páginas JSF para vincular o conteúdo dessas páginas com as informações disponibilizadas pelos managed beans.

Expression Language

Como já mencionamos, os componentes JavaServer Faces de páginas web podem acessar as propriedades do managed bean através de expressões especiais de “navegação” que seguem as regras da JSF Expression Language. Normalmente uma expressão de navegação começa com o nome de um managed bean. Vamos, por exemplo, analisar a expressão a seguir:

 

#{alunosMB.aluno.email}

 

Essa expressão navega para os elementos internos da instância do managed bean associado ao nome “alunosMB”. De acordo com a Listagem 1, este managed bean possui um atributo do tipo Aluno, que por sua vez possui outros atributos. Uma expressão pode entrar em funcionamento duas vezes durante a utilização de uma página web:

1.      Quando a página é requisitada pelo browser, ocorre uma operação de leitura no modelo de negócios para preencher dinamicamente algum elemento da página:

alunosMB.getAluno().getEmail();

2.     Quando a página é submetida (submit) para o servidor ocorre uma operação de modificação no estado modelo de negócios:

alunosMB.getAluno().setEmail( <conteúdo de um campo de input> );

 

Acompanhe em profundidade o funcionamento do JavaServer Faces no quadro “Ciclo de vida de uma página JSF”.

 

Listagem 1. Trecho do código fonte do managed bean AlunosMB

// ... Declaração de pacote e importações omitidos

 

public class AlunosMB {

  // Todos os atributos estão encapsulados através

  // de getters e setters padrão que foram omitidos

  private Aluno aluno;

  private String nomeConsulta;

  private ListDataModel alunosByName;

     

  public String cadastrarNovo() {

    this.aluno = new Aluno();

    return "editar";

  }

 

  public String editarAluno() {

    this.aluno = (Aluno) this.alunosByName.getRowData();

    return "editar";

  }

 

  public String listar() {

    this.alunosByName = null;

    if (this.nomeConsulta == null || this.nomeConsulta.length() == 0) {

      JSFHelper.addGlobalMessage("Digite um nome válido");

    } else {

      EntityManager em = JPAHelper.createEntityManager();

      GerenciadorAlunos ga = new GerenciadorAlunos();

      ga.setEntityManager(em);

      try {

        List<Aluno> alunos = ga.getByNome("%" + this.nomeConsulta + "%");

        if (alunos.size() == 0) {

          JSFHelper.addGlobalMessage("Nenhum aluno encontrado.");

        }

        this.alunosByName = new ListDataModel(alunos);

      } catch (ControleMatriculaException e) {

        JSFHelper.addGlobalMessage(e.getMessage());

        e.printStackTrace();

      } finally {

        em.close();

      }

    } ...

Quer ler esse conteúdo completo? Tenha acesso completo