Introdução ao NetBeans

Este artigo apresenta diversas funcionalidades presentes no NetBeans, que buscam aumentar a produtividade no desenvolvimento de aplicações. Uma aplicação real vai sendo desenvolvida durante o artigo e os recursos do NetBeans vão sendo explorados a cada passo da implementação.

Desenvolvedores de aplicações Java encontrarão neste artigo diversas funcionalidades interessantes do NetBeans para acelerar o processo de desenvolvimento, explicadas com base em uma aplicação real.

Este tema é útil para desenvolvedores de aplicações que têm interesse em conhecer mais sobre alguns dos recursos da IDE NetBeans visando aumentar a produtividade e a qualidade dos sistemas.

O NetBeans possui um conjunto de ferramentas capaz de gerar código e arquivos de configuração, auxiliar no empacotamento e instalação de aplicações, renomear elementos do código, entre outras. Tudo isto através de assistentes, que dão o suporte necessário que o desenvolvedor precisa para se preocupar mais com a lógica de negócio e menos com implementações secundárias. Este artigo busca explorar recursos úteis do NetBeans através de uma aplicação que será desenvolvida como exemplo.

O NetBeans é um dos ambientes de desenvolvimento mais utilizados pelos desenvolvedores Java. Mais do que um editor de código, ele possui um conjunto de ferramentas que auxiliam a programação de tarefas comuns relacionadas à implementação de aplicações. Um exemplo disto são os assistentes, que facilitam o processo de configuração e também geram código, dando o suporte necessário que o desenvolvedor precisa para se preocupar mais com a lógica de negócio do que está sendo desenvolvido e menos com implementações secundárias.

Imagine que você está no meio do desenvolvimento de um projeto e, por algum motivo, precisa alterar o nome de um método de uma determinada classe, invocado em diversos pontos do código. Ou então que você tenha uma série de classes com atributos e precisa implementar os métodos getters e setters manualmente, para todas elas. Ou na hora de executar sua aplicação web você precisa completar diversos passos até conseguir instalá-la no servidor, isto toda vez que você altera o código. Estes são apenas alguns dos problemas que você pode enfrentar durante o processo de implementação de um projeto e que, certamente vão tomar bastante tempo se uma ferramenta adequada não for utilizada.

Esta ferramenta é uma IDE (Integrated Development Environment), ou ambiente integrado de desenvolvimento. Como o seu nome diz, ela permite integrar, de forma automática, os elementos necessários durante o processo de desenvolvimento, como a utilização de bancos de dados, instalação da aplicação em um servidor, etc. Somado a isto, está a capacidade que as IDEs têm de proporcionar a solução para problemas usuais de desenvolvedores, como a necessidade de alteração segura de nome de elementos (classes, métodos, variáveis, etc.), refactoring, geração de código, busca por referências a um determinado elemento, debug passo a passo do código, etc. O ideal é que o desenvolvedor utilize o seu tempo – muitas vezes escasso – se preocupando em implementar a lógica de funcionamento da aplicação em si e, por este motivo, utilizar IDEs em projetos de pequeno, médio e grande porte pode trazer um ganho significativo de tempo, aumentando bastante a produtividade.

Atualmente, as principais IDEs gratuitas disponíveis no mercado são o NetBeans e o Eclipse. Mesmo sendo gratuitas, são ferramentas de muita qualidade e bastante semelhantes em termos de funcionalidades. Basicamente tudo o que você consegue fazer em uma, você consegue fazer de alguma forma na outra.

Este artigo busca explorar recursos interessantes – e muito úteis – do NetBeans. Para que isto seja feito de forma prática, uma aplicação será desenvolvida como exemplo. Ela será detalhada e parte do seu código será exibido a fim de demonstrar os recursos da ferramenta que o desenvolvedor pode utilizar. O lançado NetBeans 7.0 é o ambiente de desenvolvimento utilizado para criar a aplicação deste artigo, e o mesmo pode ser obtido gratuitamente na internet (consulte a seção Links no final do artigo para saber onde procurar).

Descrição da aplicação e tecnologias utilizadas

Para mostrar os recursos do NetBeans, uma aplicação chamada Corrida Favorita será desenvolvida a título de exemplo. Ela possui uma interface web onde usuários que correm podem cadastrar informações a respeito de corridas que gostam de realizar, como um nome de identificação, distância e informações sobre o trajeto. Nesta interface também é possível realizar uma pesquisa por corridas existentes de acordo com alguns critérios. Quem visualiza informações de uma corrida pode adicionar comentários a ela e recomendá-la ou não, de forma que estes comentários ficam disponíveis a todos que visualizam os dados. Outra informação relevante é que todos os usuários precisam se cadastrar previamente e fazer login no site para poderem acessar as funcionalidades de criação e pesquisa de corridas.

A aplicação que será desenvolvida neste artigo utilizará a tecnologia JSF para exibição das páginas. Já a camada de negócio será implementada com o uso de EJBs e o acesso ao banco de dados Java DB será feito com o uso de JPA. O servidor de aplicação utilizado será o GlassFish.

É importante mencionar também que a aplicação a ser desenvolvida neste artigo tem fins didáticos. Logo, é possível que, numa aplicação real, existam formas melhores de implementar algumas partes do código. Além disso, o artigo não apresentará o código-fonte completo da aplicação, pois ele é muito extenso e o objetivo é focar nas facilidades que o NetBeans proporciona ao desenvolvedor, e não na implementação em si. O código-fonte completo pode ser obtido no site da DevMedia.

Criando o projeto EJB

A construção da aplicação será iniciada a partir da sua camada de negócio. Logo, é necessária a criação de um projeto EJB (onde a lógica de negócio será implementada) e de um projeto Enterprise Application, que tem por finalidade englobar os projetos EJB e web (que será explicado em outro momento).

O conceito de Enterprise Application está relacionado com o empacotamento de aplicações no Java EE. Normalmente, uma aplicação completa é composta por diversos módulos, os quais são representados por arquivos WAR (Web ARchive) e JAR (Java ARchive). O primeiro representa os módulos web de uma aplicação, enquanto o segundo representa os módulos EJB e também classes utilitárias comuns a diversos módulos. Com o objetivo de juntar todos os módulos em um arquivo só e facilitar a distribuição e instalação, foi criado o arquivo EAR (Enterprise ARchive). Ele é o artefato gerado a partir de um projeto Enterprise Application e representa a aplicação por completo. É este arquivo que deve ser instalado no servidor de aplicações, tornando possível a sua execução.

O NetBeans possui uma grande quantidade de assistentes e você terá contato com o primeiro deles para criar o projeto EAR. Acesse File | New Project > Java EE > Enterprise Application e clique em Next. A Figura 1 mostra a primeira tela do assistente de criação do projeto.

Primeira tela do assistente da criação do projeto
EAR
Figura 1. Primeira tela do assistente da criação do projeto EAR.

A primeira informação que deve ser fornecida é o nome do projeto (neste caso ele foi chamado de Corrida). É necessário também definir um diretório onde este projeto será armazenado. Os outros dados do assistente dizem respeito à criação de um diretório para o armazenamento das bibliotecas (não será utilizado neste caso) e se o projeto deve ser definido como padrão. Marque este projeto como padrão, pois isto facilita a execução da aplicação no momento adequado. Clique em Next para ir para a próxima (e última) tela do assistente, que pode ser vista na Figura 2.

Segunda
tela do assistente da criação do projeto EAR
Figura 2. Segunda tela do assistente da criação do projeto EAR.

A tela seguinte permite realizar mais algumas configurações do projeto. Primeiramente, é necessário definir o servidor onde este projeto será instalado. O NetBeans 7.0 possui suporte ao GlassFish 3.1, que já vem configurado por padrão. Caso você deseje configurar outro servidor para executar a sua aplicação, clique em Add e você terá acesso a outro assistente, onde poderá configurar outros servidores como Tomcat, JBoss ou WebLogic. A definição de um servidor neste momento proporciona uma total integração entre o desenvolvimento e a execução da aplicação, uma vez que o NetBeans fará automaticamente a inicialização do servidor configurado e a instalação da aplicação (isto será visto na prática mais adiante).

Além do servidor, é preciso definir a versão do Java EE utilizada pela aplicação. Neste exemplo, o Java EE 6 será utilizado. Não é necessário marcar a opção para habilitar os contextos e injeção de dependência, já que esta aplicação não utilizará o CDI (Context Dependency Injection). O CDI é uma novidade do Java EE 6 e permite que o contêiner controle o ciclo de vida de objetos e forneça referências a eles de forma automática.

Por último, o NetBeans permite que os módulos associados ao projeto EAR sejam criados já neste momento. Confirme a criação do projeto EJB apenas (o projeto web será criado e associado ao projeto EAR num momento futuro). Ao clicar em Finish, os dois projetos (Corrida e Corrida-ejb) serão criados e automaticamente configurados. A partir de agora já é possível começar a pensar na implementação da aplicação.

Criando a camada de persistência

Para a aplicação Corrida Favorita, a API utilizada para o gerenciamento da persistência é a JPA. A JPA (Java Persistence API) é um mecanismo que facilita o mapeamento entre o modelo de objetos e o relacional, possibilitando o armazenamento de informações de objetos em tabelas de um banco de dados e a posterior recuperação das mesmas, abstraindo o uso da linguagem SQL e dos detalhes específicos relacionados ao servidor onde os dados estão armazenados.

A utilização da JPA para gerenciar a camada de persistência de aplicações não é obrigatória, mas facilita bastante a programação. Há algum tempo atrás, era necessário escrever manualmente todo o código de interação entre as aplicações e os bancos de dados utilizando JDBC. Percebeu-se então que, de alguma forma, o modelo das classes das aplicações poderia ser mapeado ao modelo de tabelas do banco de dados de forma automática. Foi esta proposta que ocasionou o surgimento do framework Hibernate e, mais tarde, a especificação da JPA.

Implementar a camada de persistência desta aplicação é uma tarefa que pode ser dividida em três partes. A primeira é a criação das entidades, que serão persistidas através do uso da JPA. A segunda diz respeito às configurações necessárias, que envolvem a criação de uma persistence unit e de uma data source. Por fim, a terceira é a criação das classes de DAO (Data Access Object), utilizadas para manipular as entidades. Para estas três partes, o NetBeans possui assistentes que auxiliam na criação das classes e dos arquivos de configuração, o que facilita bastante o trabalho do desenvolvedor.

Gerando as entidades

Serão criadas três entidades para a aplicação: Corrida, Usuario e Comentario, que representam as corridas, usuários e comentários feitos por usuários, respectivamente. A Figura 3 mostra o diagrama de classes com os atributos de cada entidade.

Diagrama de classe das entidades
Figura 3. Diagrama de classe das entidades.

Ao olhar para as entidades existentes e seus relacionamentos, já é possível imaginar como elas podem ser mapeadas para o modelo relacional, utilizado no armazenamento de informações no banco de dados. Existirão três tabelas, uma para cada entidade, e cada atributo é mapeado para uma coluna em uma tabela. A tabela comentario, por exemplo, terá as colunas id, datacomentario, texto, recomendado, corrida_id e usuário_id, onde id será a chave primária e corrida_id e usuário_id serão chaves estrangeiras para as tabelas corrida e usuario, respectivamente.

A boa notícia é que, com a JPA, você não precisa se preocupar com as tabelas do banco de dados. Basta que você enxergue o conjunto de entidades existentes e os seus relacionamentos, que a JPA gerencia todo o acesso ao banco de dados. Aliás, ela também identifica os relacionamentos entre as tabelas (através das chaves estrangeiras) e carrega estas informações adequadamente nas entidades.

Os nomes das tabelas e colunas do banco de dados não precisam seguir os nomes e atributos das entidades. É possível que anotações como @Table e @Column sejam utilizadas na entidade, a fim de definir dados específicos acerca do mapeamento.

O NetBeans possui também recursos para criar as classes que representam as entidades. Com o projeto Corrida-ejb selecionado, acesse File | New File > Persistence > Entity Class e clique em Next. Será exibido um assistente para a criação de entidades, como pode ser visto na Figura 4.

Assistente para criação de entidades
Figura 4. Assistente para criação de entidades.

Neste assistente, é necessário definir um nome para a entidade e o pacote onde ela será criada. O exemplo mostrado na Figura 4 é relacionado à criação da entidade Corrida no pacote javamagazine.corrida.entity. É preciso definir também a classe que representará a chave da entidade (neste caso, java.lang.Integer). Isto é necessário porque toda entidade persistida pela JPA deve, obrigatoriamente, ter um ou mais atributos que a identificam de forma única.

Ainda neste assistente, é possível também solicitar ao NetBeans a geração de uma persistence unit, necessária para que a persistência com o uso de JPA funcione (a persistence unit configura o mecanismo de persistência). Neste momento ela não será criada, uma vez que isto será feito na sequência, depois que a data source for configurada.

Depois de clicar em Finish, a classe Corrida é gerada com uma implementação padrão baseada em um template, como pode ser visto na Listagem 1. Note a presença da anotação @Entity, que indica que a classe é uma entidade a ser persistida pela JPA, e também de @Id, que define o atributo que representa a chave primária. A anotação @GeneratedValue define a estratégia para a geração da chave primária, onde GenerationType.AUTO indica que ela deve ser gerada de forma automática, utilizando o mecanismo padrão do banco de dados (normalmente com base em uma sequence ou coluna de auto-incremento). O próximo passo é editar este arquivo, adicionando os atributos da classe Corrida, da forma como é mostrado na Listagem 2.

Algumas anotações são utilizadas nos atributos, a fim de configurar adequadamente a entidade. Além de @Id, são utilizadas @Column, que configura propriedades das colunas na tabela (nullable = false indica que a coluna não aceita valores nulos); @Temporal com o valor TemporalType.DATE, que define que o atributo do tipo Date representa uma data que desconsidera as horas do dia; e @OneToMany e @ManyToOne, que estabelecem o relacionamentos de um-para-muitos e muitos-para-um com as entidades Comentario e Usuario, respectivamente. É importante lembrar que este código só compilará adequadamente depois que as entidades Comentario e Usuario forem criadas.

Listagem 1. Classe Corrida gerada pelo NetBeans.


  @Entity
  public class Corrida implements Serializable {
    private static final long serialVersionUID = 1L;
   
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;
   
    public Integer getId() {
      return id;
    }
   
    public void setId(Integer id) {
      this.id = id;
    }
   
    public int hashCode() {
      int hash = 0;
      hash += (id != null ? id.hashCode() : 0);
      return hash;
    }
   
    public boolean equals(Object object) {
      // TODO: Warning - this method won"t work in the case the id fields are not set
      if (!(object instanceof Corrida)) {
        return false;
      }
      Corrida other = (Corrida) object;
      if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
        return false;
      }
      return true;
    }
   
    public String toString() {
      return "javamagazine.corrida.entity.Corrida[ id=" + id + " ]";
    }
  }

Listagem 2. Atributos da classe Corrida.


  @Entity
  public class Corrida implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;
   
    @Column(nullable = false)
    private String nome;
    
    @Temporal(TemporalType.DATE)
    @Column(nullable = false)
    private Date dataCorrida;
    
    @Column(nullable = false)
    private Integer distancia;
    
    @Column(nullable = false)
    private String descricao;
    
    @ManyToOne(optional = false)
    private Usuario usuario;
    
    @OneToMany(mappedBy = "corrida")
    private Set<Comentario> comentarios = new LinkedHashSet<Comentario>();
   
    //métodos getters e setters...
  }

Uma classe que representa uma entidade deve ter também métodos getters e setters que possibilitem a leitura e manipulação dos atributos. Estes métodos nada mais são do que uma forma de expor o valor dos atributos externamente e também possibilitar que eles sejam alterados, uma vez que os atributos em si são declarados como privados (private). De acordo com a convenção, as assinaturas dos métodos getter e setter para um atributo distancia seriam, respectivamente, getDistancia() e setDistancia(Integer distancia). O primeiro não retorna qualquer informação (void), enquanto o segundo retorna a distância como um Integer.

Dependendo do número de atributos, criar estes métodos manualmente pode demandar uma grande quantidade de tempo. Para acelerar o processo, o NetBeans conta com um gerador automático de getters e setters. Assim, posicione o cursor no local onde a geração dos métodos deve ser iniciada, clique com o botão direito e selecione Insert Code > Getter and Setter. A Figura 5 mostra o assistente para criar os métodos. Serão exibidos os atributos da classe e, para cada atributo marcado, os métodos serão gerados.

Assistente para gerar os métodos getters e setters
Figura 5. Assistente para gerar os métodos getters e setters.

O NetBeans também possui a opção de gerar apenas os métodos getters ou apenas os setters. Para fazer isto, clique com o botão direito no código e escolha as opções Insert Code > Getter ou Insert Code > Setter, respectivamente.

saiba mais Confira em nosso Fórum Getters and Setter com NetBeans

Agora que a entidade Corrida está finalizada, basta repetir o mesmo processo para a criação das outras entidades (Usuario e Comentario).

Criando a data source e a persistence unit

Para que a JPA possa persistir as entidades, é necessária a configuração de uma persistence unit, que indica qual data source será utilizada pelo mecanismo de persistência. Uma data source define os parâmetros de conexão com o banco de dados e, por ser um pré-requisito para a persistence unit, deve ser criada primeiro.

Uma data source é um componente que funciona como um repositório de conexões com o banco de dados. Normalmente estas conexões ficam ativas e armazenadas em um pool, aguardando até serem requisitadas. Quando a aplicação necessita de uma conexão, a data source entrega a ela uma que está disponível no pool, que retorna a ele depois de ser utilizada. Este mecanismo é bastante interessante do ponto de vista de performance, pois evita que conexões tenham que ser criadas e destruídas a todo o momento. Por tudo isto, um pool de conexões bem dimensionado associado a uma data source é fundamental para aplicações com acesso simultâneo de usuários.

Para criar a data source, é necessário associá-la a um pool de conexões. Este pool pode ser criado pelo NetBeans através do menu File | New File > GlassFish > JDBC Connection Pool. A Figura 6 mostra a primeira tela do assistente, onde devem ser fornecidos um nome para o pool de conexões (jmPool) e o tipo de banco de dados utilizado na conexão (o Java DB será utilizado na aplicação desenvolvida neste artigo).

Configurando o nome do pool de conexões e o tipo de
banco de dados
Figura 6. Configurando o nome do pool de conexões e o tipo de banco de dados.

Ao clicar em Next, a próxima tela é exibida e nela é necessário realizar as configurações de acesso ao banco de dados. Ela pode ser visualizada na Figura 7. Os itens Datasource Classname e Resource Type podem ser mantidos com os valores padrão, mas você deve configurar adequadamente as propriedades para que a conexão no banco de dados possa ser realizada. Elas devem estar de acordo com o que está descrito na Tabela 1. Depois disso, clique em Finish e o pool de conexões será criado.

Configurando as propriedades de acesso ao banco de
dados
Figura 7. Configurando as propriedades de acesso ao banco de dados.

Propriedade

Valor

URL

jdbc:derby://localhost:1527/corrida

serverName

localhost

PortNumber

1527

DatabaseName

corrida

User

app

Password

app

Tabela 1. Propriedades de conexão com o banco de dados.

Criado o pool de conexões, chegou o momento da criação da data source. Para isto, basta utilizar outro assistente do NetBeans, acessado através do menu File | New File > GlassFish > JDBC Resource e que pode ser visto na Figura 8. A configuração exige, basicamente, um nome JNDI (definido aqui comojdbc/jmDS) e um pool de conexões associado (será utilizado o jmPool criado anteriormente). Ao clicar em Finish o processo de criação é finalizado.

Os assistentes de criação do pool de conexões e da data source geram informações que ficam armazenadas no arquivo glassfish-resources.xml, dentro da pasta Server Resources do projeto Corrida-ejb.

Definição dos dados da data source
Figura 8. Definição dos dados da data source.

Com a data source devidamente criada e configurada, falta agora criar o banco de dados corrida, onde as entidades da aplicação serão armazenadas. A grande vantagem de utilizar um ambiente integrado como o NetBeans é a possibilidade de interagir com o servidor de banco de dados diretamente de dentro da ferramenta de desenvolvimento, não sendo necessário utilizar ferramentas externas.

Assim, acesse o menu Window | Services e uma lista de itens será exibida do lado esquerdo da tela. Acesse Databases, clique com o botão direito sobre Java DB e selecione Create Database. Os dados devem ser preenchidos de acordo com o descrito na Tabela 2 e devem ser os mesmos configurados quando da criação do pool de conexões.

Propriedade

Valor

Database Name

corrida

User Name

app

Password

app

Confirm Password

app

Tabela2. Dados para a criação do banco de dados.

Terminado este processo, o NetBeans vai iniciar o servidor do Java DB automaticamente e efetivar a criação do banco de dados. Além disso, será criada uma entrada de conexão na lista dos Services, como mostra a Figura 9. Clicando com o botão direito sobre ela, é possível conectar-se ao banco de dados, visualizar as estruturas de tabelas e até executar comandos SQL, diretamente do NetBeans.

 Banco de dados criado e acessível pela lista dos Services

Figura 9. Banco de dados criado e acessível pela lista dos Services.

Para finalizar a configuração da JPA, é preciso criar agora a persistence unit. Para isso, acesse File | New File > Persistence > Persistence Unit e clique em Next. O assistente de criação pode ser visto na Figura 10. A primeira informação importante é definir um nome para ela, o qual será referenciado depois pelas classes da aplicação que utilizam uma instância de EntityManager. É preciso também definir um persistence provider, que por padrão é o EclipseLink, e também a data source associada (deve ser utilizada a data source jdbc/jmDS, criada anteriormente).

Outro detalhe importante com relação ao persistence provider é que você pode configurá-lo para criar as tabelas no banco de dados de forma automática, com base nas entidades da aplicação. Para isto, em Table Generation Strategy utilize Create (para criar as tabelas) ou Drop and Create (para excluir as tabelas e gerá-las novamente quando a aplicação for reinstalada).

Configuração do persistence unit
Figura 10. Configuração do persistence unit.

Ao clicar em Finish, o persistence unit é criado. O assistente gera então o arquivo persistence.xml dentro da pasta Configuration Files do projeto Corrida-ejb, que é obrigatório para o correto funcionamento da JPA.

O NetBeans possui um editor gráfico do arquivo persistence.xml, que permite editá-lo de forma mais intuitiva do que manipular diretamente o conteúdo em XML. Esta mesma facilidade também existe para o arquivo web.xml, encontrado em projetos web.

Criando as classes de DAO

Quando uma aplicação utiliza persistência de dados, é importante que sejam criadas classes que encapsulem o acesso ao banco de dados. Estas classes são chamadas de DAO (Data Access Object) e normalmente possuem métodos que interagem com as entidades persistentes (gravar, excluir, ler, etc.). Como uma classe DAO interage diretamente com uma entidade específica, é interessante que exista uma relação de um para um entre elas, isto é, um DAO para cada entidade.

Assim como a criação manual de métodos getters e setters, a criação de classes DAO também pode demandar bastante tempo se o número de entidades da aplicação for grande. Logo, para facilitar o trabalho do desenvolvedor, o NetBeans é capaz de gerar as classes DAO das entidades da aplicação de forma simples e rápida.

As classes DAO da aplicação serão representadas por stateless session beans. Os session beans são EJBs (Enterprise JavaBeans), isto é, componentes que implementam métodos de negócio de uma aplicação. Eles possuem uma interface que permite o acesso aos métodos do componente, e podem ser do tipo stateful (se mantiverem o estado entre invocações) ou stateless (se não mantiverem). Na prática, isto significa que um stateful session bean é dedicado a um único cliente (neste caso um cliente pode ser um usuário da aplicação), sendo seguro o armazenamento de dados em atributos quando da chamada de métodos. Já uma instância de um stateless session bean pode ser compartilhada entre vários clientes, o que torna a utilização de atributos inviável. Consequentemente, todos os métodos chamados em um stateless session bean devem receber todos os parâmetros dos quais necessitam para fazerem o processamento. Como um DAO não está atrelado a um cliente específico e não precisa manter estado, ele será representado por um session bean do tipo stateless.

Ao escolher o tipo do bean que será criado (stateless ou stateful), considere que uma instância de um stateful session bean é dedicada a um único cliente. Logo, se houver uma quantidade muito grande de clientes acessando a aplicação em determinado momento, isto ocasionará a criação de uma grande quantidade de objetos, o que pode degradar a performance do sistema como um todo. Já uma instância de um stateless session bean pode ser compartilhada entre vários clientes, o que favorece a escalabilidade (não é necessária a existência de tantos objetos). Diante disso, a recomendação na prática é optar portateless session beans sempre que possível, e deixar os stateful session beans para situações onde o bean realmente não deve ser compartilhado.

A grande vantagem de utilizar EJBs para implementar a camada de negócios das aplicações é relacionada aos serviços disponibilizados pelo contêiner, que proporciona gerenciamento automático de transações, segurança, entre outros. Isto permite que o desenvolver foque apenas no que realmente importa, que é a implementação dos métodos de negócio dos EJBs, e delegue as outras implementações de suporte para o contêiner.

Para gerar os EJBs necessários, clique sobre o projeto Corrida-ejb e acesse File | New File > Persistence > Session Beans For Entity Classes. Ao clicar em Next, será exibido um assistente, que pode ser visto na Figura 11.

Escolha das entidades para a geração dos DAOs
Figura 11. Escolha das entidades para a geração dos DAOs.

O primeiro passo é escolher, dentre as entidades listadas do lado esquerdo, quais devem ter uma classe DAO gerada. Para estas entidades, basta movê-las para a caixa de seleção da direita utilizando as opções Add ou Add All e, em seguida, clicar em Next.

No próximo passo do assistente, exibido na Figura 12, é possível configurar os detalhes a respeito dos session beans que serão gerados. Basicamente, deve ser fornecido um pacote onde as classes serão criadas (neste caso, javamagazine.corrida.dao) e se os beans terão interfaces locais ou remotas. Para esta aplicação, optou-se pela geração de interfaces locais, uma vez que a aplicação toda será instalada no mesmo servidor (classes remotas são úteis quando os EJBs estão divididos em dois ou mais servidores na rede).

Criação dos session beans que serão os DAOs
Figura 12. Criação dos session beans que serão os DAOs.

A partir da especificação 3.1 do EJB, o uso de interfaces locais não é obrigatório. Deste modo, é possível criar um EJB sem interface que possui apenas a classe de implementação anotada com @Stateless ou @Stateful.

Ao clicar em Finish, diversos arquivos serão gerados no pacote javamagazine.corrida.dao. Para cada entidade, o NetBeans cria um arquivo com o sufixo FacadeLocal, que representa a interface do session bean, e também um com o sufixo Facade, que é a implementação do código do EJB. As Listagens 3 e 4 mostram, respectivamente, a interface CorridaFacadeLocal e a classe CorridaFacade.

Listagem 3. Interface CorridaFacadeLocal, gerada pelo NetBeans.


  @Local
  public interface CorridaFacadeLocal {
    void create(Corrida corrida);
    void edit(Corrida corrida);
    void remove(Corrida corrida);
    Corrida find(Object id);
    List<Corrida> findAll();
    List<Corrida> findRange(int[] range);
    int count();
  }

Listagem 4. Classe CorridaFacade, gerada pelo NetBeans.


  @Stateless
  public class CorridaFacade extends AbstractFacade<Corrida> implements CorridaFacadeLocal {
    @PersistenceContext(unitName = "Corrida-ejbPU")
    private EntityManager em;
    
    @Resource
    private javax.transaction.UserTransaction utx;
   
    protected EntityManager getEntityManager() {
      return em;
    }
   
    public CorridaFacade() {
      super(Corrida.class);
    }
  }

A interface de um EJB declara os métodos que podem ser acessados pelo código que irá invocá-lo. Ela recebe a anotação @Local ou @Remote, caso seja uma interface local ou remota, respectivamente. Já a classe do bean, além de implementar a interface, deve ser anotada com @Stateless ou @Stateful, dependendo se ele é stateless ou stateful, respectivamente.

Se você olhar atentamente para a interface CorridaFacadeLocal, vai perceber que o NetBeans declara diversos métodos para interagir com a entidade Corrida, como criar, remover, procurar por ID, procurar todos os registros, etc. Já a classe CorridaFacade implementa esta interface, e o objeto da classe EntityManager, declarado como atributo, referencia a persistence unit Corrida-ejbPU, criada anteriormente. Esta instância de EntityManager é o elemento da JPA que possibilita que a entidade seja persistida no banco de dados previamente configurado.

Outro detalhe a respeito da geração de classes é que o NetBeans cria uma classe extra, chamada AbstractFacade, declarada como super classe das classes de EJB e que pode ser vista na Listagem 5. Ela implementa os métodos que são comuns aos DAOs de todas as entidades, evitando a reescrita do mesmo código em diversos lugares.

Listagem 5. Classe AbstractFacade, gerada pelo NetBeans.


  public abstract class AbstractFacade<T> {
    private Class<T> entityClass;
   
    public AbstractFacade(Class<T> entityClass) {
      this.entityClass = entityClass;
    }
   
    protected abstract EntityManager getEntityManager();
   
    public void create(T entity) {
      getEntityManager().persist(entity);
    }
   
    public void edit(T entity) {
      getEntityManager().merge(entity);
    }
   
    public void remove(T entity) {
      getEntityManager().remove(getEntityManager().merge(entity));
    }
   
    public T find(Object id) {
      return getEntityManager().find(entityClass, id);
    }
   
    public List<T> findAll() {
      javax.persistence.criteria.CriteriaQuery cq = 
        getEntityManager().getCriteriaBuilder().createQuery();
      cq.select(cq.from(entityClass));
      return getEntityManager().createQuery(cq).getResultList();
    }
   
    public List<T> findRange(int[] range) {
      javax.persistence.criteria.CriteriaQuery cq = 
        getEntityManager().getCriteriaBuilder().createQuery();
      cq.select(cq.from(entityClass));
      javax.persistence.Query q = getEntityManager().createQuery(cq);
      q.setMaxResults(range[1] - range[0]);
      q.setFirstResult(range[0]);
      return q.getResultList();
    }
   
    public int count() {
      javax.persistence.criteria.CriteriaQuery cq = 
        getEntityManager().getCriteriaBuilder().createQuery();
      javax.persistence.criteria.Root<T> rt = cq.from(entityClass);
      cq.select(getEntityManager().getCriteriaBuilder().count(rt));
      javax.persistence.Query q = getEntityManager().createQuery(cq);
      return ((Long) q.getSingleResult()).intValue();
    }
  }

Todas as classes de DAO necessárias estão agora geradas e prontas para serem utilizadas. Mas para demonstrar outra funcionalidade muito útil do NetBeans, as classes geradas serão renomeadas para seguirem outro padrão, substituindo o termo Facade por DAO.

É bastante comum que haja a necessidade de renomear classes durante o desenvolvimento do projeto. O grande problema de fazer isto é que todos os elementos do código que referenciam a classe precisam ser renomeados também. Felizmente, o NetBeans gerencia isto de forma automática, identificando todas as referências e fazendo as alterações necessárias a fim de garantir que o código continue compilando mesmo após a mudança do nome.

O processo é bastante simples e funciona tanto para classes como para interfaces. Para isso, clique com o botão direito sobre o nome do arquivo a ser renomeado, que aparece na lista de arquivos do projeto, e selecione Refactor > Rename. O NetBeans exibirá uma caixa de diálogo como a da Figura 13, onde você deve fornecer o novo nome e clicar em Refactor para confirmar. Além de renomear a classe ou interface, todas as referências a ela também serão corrigidas. Repita o mesmo processo para todos os arquivos gerados no pacote javamagazine.corrida.dao.

Renomeando a classe CorridaFacade para CorridaDAO
Figura 13. Renomeando a classe CorridaFacade para CorridaDAO.

Além de renomear classes, o NetBeans permite também que métodos, atributos e variáveis tenham seus nomes alterados. Nestes casos as referências a estes elementos também são corrigidas para que o código continue compilando. Basta clicar com o botão direito sobre o elemento que deve ser renomeado e acessar o menu Refactor > Rename.

Além dos métodos definidos em AbstractDAO, cada classe DAO deve implementar seus métodos próprios. A Figura 14 mostra os métodos que devem ser criados em cada classe para esta aplicação. O NetBeans facilita o processo de criação de métodos em EJBs, e isto será abordado em detalhes na sequência, quando da criação dos componentes de negócio.

Diagrama das classes DAO
Figura 14. Diagrama das classes DAO.

Criando os componentes de negócio

Assim como os DAOs, as classes que irão conter a lógica de negócio da aplicação também serão representadas por session beans do tipo stateless. Para esta aplicação, serão criados dois EJBs: CorridaService, que possuirá os métodos para gerenciar corridas e comentários; e UsuarioService, para cadastrar usuários e realizar o login no sistema.

Criar EJBs no NetBeans é um processo simples, pois conta com a ajuda de assistentes. Após selecionar o projeto Corrida-ejb, acesse o menu File | New File > Enterprise JavaBeans > Session Bean e clique em Next. O assistente de criação de session beans será exibido, como mostra a Figura 15. É preciso fornecer o nome do EJB (CorridaService), o pacote onde ele será criado (javamagazine.corrida.service), o tipo do bean (stateless) e o tipo de interface a ser criada (local). Ao clicar em Finish, a classe CorridaService e a interface CorridaServiceLocal serão geradas no pacote escolhido e estarão prontas para receberem os métodos de negócio.

Criação do stateless session bean CorridaService
Figura 15. Criação do stateless session bean CorridaService.

A criação dos métodos negócio exige, na verdade, duas tarefas. Uma é declarar o método na interface do EJB e a outra é implementá-lo na classe do bean. Neste ponto, o NetBeans pode auxiliá-lo novamente, disponibilizando um assistente para geração de métodos de negócio em EJBs.

Para ver como isto funciona na prática, será criado agora o método cadastrarCorrida() em CorridaService, responsável por invocar o objeto CorridaDAOLocal e persistir a corrida no banco de dados. Dentro da área de código da classe, clique com o botão direito e selecione Insert Code > Add Business Method. Um assistente será exibido, de acordo com a Figura 16. Nele, é possível definir um nome para o método (cadastrarCorrida()), tipo de retorno (void), parâmetros (chamado corrida e com o tipo Corrida) e também exceções a serem lançadas, caso necessário. Ao clicar em OK, a criação do método é efetivada. As Listagens 6 e 7 mostram os métodos criados na interface CorridaServiceLocal e CorridaService, respectivamente.

Criação do método de negócio cadastrarCorrida()
Figura 16. Criação do método de negócio cadastrarCorrida().

Listagem 6. Método de negócio criado na interface CorridaServiceLocal.


  @Local
  public interface CorridaServiceLocal {
    void cadastrarCorrida(Corrida corrida);
  }

Listagem 7. Método de negócio criado na classe CorridaService.


  @Stateless
  public class CorridaService implements CorridaServiceLocal {
    public void cadastrarCorrida(Corrida corrida) {
    }
  }

Com o método declarado, a tarefa agora é implementá-lo de acordo com a lógica da aplicação. A Listagem 8 mostra como fica o método cadastrarCorrida(), cuja tarefa é delegar a persistência da entidade Corrida para o objeto CorridaDAOLocal, declarado como um atributo da classe CorridaService.

Listagem 8. Implementação do método cadastrarCorrida() da classe CorridaService.


  @Stateless
  public class CorridaService implements CorridaServiceLocal {
   
    @EJB
    private CorridaDAOLocal corridaDAO;
   
    public void cadastrarCorrida(Corrida corrida) {
      corridaDAO.create(corrida);
    }
  }

Quando a anotação @EJBé utilizada em um atributo que representa um EJB, o contêiner injeta a referência ao bean de forma automática. Por este motivo o método cadastrarCorrida() pode utilizar o atributo corridaDAO, pois ele estará inicializado corretamente no momento da chamada.

A mesma abordagem deve ser utilizada para implementar os outros métodos de negócio. Tanto de CorridaService quanto de UsuarioService. A Figura 17 mostra o diagrama de classes destes dois componentes, indicando quais métodos eles possuem.

Diagrama das classes de negócio da aplicação
Figura 17. Diagrama das classes de negócio da aplicação.

Criando o projeto web

Até o momento toda a camada de negócio já foi criada e está pronta para ser utilizada. O que falta agora é a interface web da aplicação, que será utilizada para invocar os métodos de negócio definidos nos EJBs CorridaService e UsuarioService. Ela será baseada na tecnologia JSF, que permite criar páginas dinâmicas usando um modelo baseado em componentes.

O primeiro passo é criar o projeto web, utilizando o assistente do NetBeans de criação de projetos. Use a opção do menu File | New Project > Java Web > Web Application, e no primeiro passo do assistente forneça um nome para o projeto (para esta aplicação será utilizado o nome Corrida-war) e clique em Next. No segundo passo outras configurações devem ser realizadas, como mostra a Figura 18. A primeira informação é a respeito de qual projeto EAR o novo projeto web deve fazer parte. Neste ponto, o Corrida-ear deve ser escolhido, o que fará com que o NetBeans atrele este novo projeto como sendo um módulo do projeto EAR, da mesma forma que o projeto EJB criado anteriormente. Lembre-se que o projeto web é um dos módulos que compõem a Enterprise Application. Outra informação importante definida neste ponto é o context path, que indica o caminho utilizado para acessar a interface web da aplicação. Neste caso foi escolhido /Corrida, o que significa que toda a aplicação será acessada tendo como base este contexto definido na URL.

Configurando o projeto Corrida-war
Figura 18. Configurando o projeto Corrida-war.

Ao clicar em Next, será exibido o terceiro e último passo da criação do projeto. O NetBeans permite preparar a integração do mesmo com alguns frameworks bastante utilizados, tudo de forma automática, como mostra a Figura 19. Como neste caso o projeto utilizará JSF, este framework deve ser marcado. Além do JSF, o NetBeans pode gerar o código necessário para integrar a aplicação com os frameworks Spring Web MVC, Struts e Hibernate. Nas abas inferiores é possível realizar configurações mais refinadas, como a versão do JSF, utilização de Facelets ou JSPs para a criação das páginas, o padrão de URL interceptado pelo JSF, dentre outras. É possível manter o padrão sugerido, uma vez que ele é o ideal para grande parte das aplicações.

A tecnologia JSF pode trabalhar com duas linguagens para a construção da camada de visualização das aplicações, isto é, as páginas que serão dinamicamente geradas para o usuário. A primeira é a utilização de JSPs (JavaServer Pages), que misturam código HTML com código Java. Mas a partir do JSF 2.0 a tecnologia preferencial para a definição das páginas é chamada Facelets, que permite trabalhar com componentes representados hierarquicamente, através de uma linguagem de marcação similar ao HTML.

Outro ponto importante com relação ao JSF é que, para ele funcionar, a aplicação deve ter um servlet específico declarado no arquivoweb.xml (javax.faces.webapp.FacesServlet) e mapeado para uma URL, normalmente /faces/*. Toda vez que uma requisição for feita utilizando este padrão de URL, ela passa pelo JSF, que faz o processamento necessário para a renderização da página. Felizmente o desenvolvedor não precisa se preocupar com esta etapa de configuração, uma vez que o assistente do NetBeans de geração de projetos web com suporte à JSF realiza este processo automaticamente.

Definindo os frameworks que serão utilizados pelo
projeto web
Figura 19. Definindo os frameworks que serão utilizados pelo projeto web.

Ao clicar em Finish, o projeto Corrida-war é criado e, neste momento, já possui suporte ao JSF. O NetBeans cria, inclusive, um arquivo de exemplo chamado index.xhtml, gerado a partir de um template e que pode ser utilizado como ponto de partida para a criação de uma página JSF. O seu conteúdo pode ser visto na Listagem 9.

Listagem 9. Arquivo index.xhtml gerado pelo NetBeans.


  <?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">
    <h:head>
      <title>Facelet Title</title>
    </h:head>
    <h:body>
      Hello from Facelets
    </h:body>
  </html>

Criação das páginas JSF e dos managed beans

Uma das características do JSF é a utilização de managed beans em conjunto com as páginas. Um managed bean é um componente gerenciado pelo contêiner que trabalha junto com a página JSF para fornecer dados a ela e também para receber dados submetidos. O NetBeans possui facilidades para criar tanto as páginas JSF quanto os managed beans. Como exemplo, será mostrada a criação da funcionalidade de login da aplicação, que envolve a página login.xhtml e o managed bean LoginBean.

Para criar a página JSF, use o menu File | New File > JavaServer Faces > JSF Page. As informações mais importantes neste caso são o nome da página (login) e o tipo de sintaxe utilizada na criação do arquivo (Facelets), como pode ser visto na Figura 20.

Criando a página JSF para o login na aplicação
Figura 20. Criando a página JSF para o login na aplicação.

Ao clicar em Finish, o arquivo login.xhtml será criado com base em um template, bastando então fazer as alterações necessárias no arquivo. A Listagem 10 mostra o arquivo pronto. Note que a página referencia o managed bean LoginBean (que será criado na sequência) através de expressões como #{loginBean.email}, #{loginBean.senha} e #{loginBean.login}. Esta é a forma que o JSF utiliza para ler e atribuir dados ao bean e também invocar seus métodos. Aliás, neste ponto o NetBeans também pode auxiliar o desenvolvedor, pois o mesmo assistente de código disponível na criação de código Java (através do uso do atalho Ctrl+Espaço) está presente também no arquivo JSF, permitindo acessar propriedades e métodos do bean de forma fácil, além de facilitar o processo de inserção de componentes JSF na página.

Listagem 10. Arquivo login.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:h="http://java.sun.com/jsf/html"
        xmlns:f="http://java.sun.com/jsf/core">
    <h:head>
      <title>Login</title>
      <link rel="stylesheet" type="text/css" href="/corrida/corrida.css" />
    </h:head>
    <h:body>
      <h1>Login no Site</h1>
      <h:form>
        <table border="0" cellpadding="2">
          <tbody>
            <tr>
              <td><h:outputText value="E-mail:" /></td>
              <td>
                <h:inputText id="email" value="#{loginBean.email}" required="true" 
                  requiredMessage="Forneça um e-mail" />
              </td>
              <td>
                <h:message style="color: red" for="email" />
              </td>
            </tr>
            <tr>
              <td><h:outputText value="Senha:" /></td>
              <td>
                <h:inputSecret id="senha" value="#{loginBean.senha}" required="true" 
                  requiredMessage="Forneça uma senha" />
              </td>
              <td>
                <h:message style="color: red" for="senha" />
              </td>
            </tr>
          </tbody>
        </table>
        <h:commandButton id="submit" value="Autenticar" action="#{loginBean.login}" />
        <br/><br/>
        <h:outputLink value="cadastrar-usuario.xhtml">Cadastrar Usuário</h:outputLink>
      </h:form>
    </h:body>
  </html>

Depois de criada a página, é a vez do managed bean LoginBean. Para isto, utilize o menu File | New File > JavaServer Faces > JSF Managed Bean. O assistente pode ser visto na Figura 21 e permite o fornecimento de uma série de dados.

Um managed bean deve ser representado por uma classe de um pacote, que neste caso será javamagazine.corrida.bean.LoginBean. Ele deve também ter um nome, que será utilizado pela página JSF para referenciá-lo, e um escopo, que determina o seu tempo de vida. Neste caso ele é definido como session, pois o bean armazenará os dados do usuário logado no sistema e deve existir mesmo entre as requisições feitas pelo usuário.

Criando o managed bean LoginBean
Figura 21. Criando o managed bean LoginBean.

Ao clicar em Finish, o managed bean é criado com base em um template. Depois de pronto, ele fica como mostrado na Listagem 11. O código já é gerado com as anotações @ManagedBean e @SessionScoped, que definem que esta classe se trata de um managed bean com escopo de sessão. A Figura 22 mostra como fica a tela da funcionalidade de login, já finalizada.

Listagem 11. Managed bean LoginBean.


  @ManagedBean
  @SessionScoped
  public class LoginBean implements Serializable {
    @EJB
    private UsuarioServiceLocal usuarioService;
    private String email;
    private String senha;
    private Usuario loggedUser;
   
    public String login() {
      Usuario usuario = usuarioService.login(email, senha);
      if (usuario != null) {
        loggedUser = usuario;
        email = null;
        senha = null;
        return "home";
      }
      return null;
    }
   
    public String logout() {
      loggedUser = null;
      FacesContext context = FacesContext.getCurrentInstance();
      HttpSession session = (HttpSession) context.getExternalContext().getSession(true);
      session.invalidate();
      return "login";
    }
 //métodos getters e setters...
}

Tela
de login da aplicação
Figura 22. Tela de login da aplicação.

Ao criar um managed bean com escopo do tipo session, é importante que a classe implemente a interface Serializable. Isto porque o objeto será colocado na sessão do usuário e o servidor de aplicação pode, em alguns casos, gravar esta informação em disco ou até transferi-la pela rede (no caso do uso de clusters). O gerador de código do NetBeans não declara a implementação da interface, portanto é necessário que isto seja feito manualmente.

Um managed bean deve sempre ter um escopo associado, que determina o seu tempo de vida. O escopo utilizado neste exemplo foi o de sessão (@SessionScoped), que mantém o bean ativo enquanto a sessão do usuário existir. Outros escopos importantes são o de requisição (@RequestScoped), onde o bean existe apenas durante uma única requisição e depois é destruído; e o de aplicação (@ApplicationScoped), que existe durante todo o tempo que a aplicação está funcionando. Além destes, o JSF possui outro escopo, chamado de conversação (@ConversationScoped), e que é um meio termo entre os escopos de requisição e sessão. Neste caso o desenvolvedor demarca o início e o fim da conversação de forma explícita, e o contêiner fica responsável por garantir que o managed bean (e, consequentemente, os seus dados) estejam disponíveis durante este período.

Configurando a navegação entre as páginas

Uma aplicação web composta por diversas páginas deve ter um fluxo bem definido de como ocorrerá a transição entre elas. Este fluxo define, por exemplo, para qual página o usuário será direcionado quando criar uma nova corrida ou então quando pesquisar corridas existentes.

Em JSF, esta configuração deve ser realizada no arquivo faces-config.xml, localizado dentro do diretório WEB-INF da aplicação. Quando o NetBeans cria o projeto web com suporte à JSF, este arquivo não é criado de forma automática. No entanto, existe um assistente que permite criá-lo de forma rápida. Com o projeto Corrida-war selecionado, acesse o menu File | New File > JavaServer Faces > JSF Faces Configuration e confirme a criação do arquivo (o assistente já traz preenchidas todas as informações necessárias para a geração).

Com o arquivo criado, o próximo passo é definir as regras de navegação. Neste ponto, o NetBeans pode auxiliar bastante, pois ele conta com um editor gráfico que exibe as páginas JSF da aplicação em forma de retângulos e permite que a ligação entre elas seja feita através de setas, que representam as regras de navegação. A Figura 23 mostra o editor com as regras configuradas para a aplicação Corrida Favorita. Já a Listagem 12 mostra um trecho do arquivo faces-config.xml, cujos dados são gerados pelo editor gráfico do NetBeans.

Editor gráfico das regras de navegação das páginas JSF
Figura 23. Editor gráfico das regras de navegação das páginas JSF.

Listagem 12. Trecho do arquivo faces-config.xml.


  ...
    <navigation-rule>
      <from-view-id>/home.xhtml</from-view-id>
      <navigation-case>
        <from-outcome>search</from-outcome>
        <to-view-id>/home.xhtml</to-view-id>
      </navigation-case>
      <navigation-case>
        <from-outcome>create</from-outcome>
        <to-view-id>/cadastrar-corrida.xhtml</to-view-id>
      </navigation-case>
      <navigation-case>
        <from-outcome>login</from-outcome>
        <to-view-id>/login.xhtml</to-view-id>
      </navigation-case>
      <navigation-case>
        <from-outcome>view</from-outcome>
        <to-view-id>/detalhes-corrida.xhtml</to-view-id>
      </navigation-case>
    </navigation-rule>
  ... 

A definição das regras de navegação é feita por tags navigation-rule. Uma tag deste tipo é composta por uma tag from-view-id, que indica a página JSF de origem, e por tags navigation-case, que indicam as páginas de destino. Note que a partir de um local é possível navegar para um ou mais destinos. Cada página de destino é identificada por um nome, definido na tag from-outcome, e também pelo caminho da página JSF propriamente dita. Esta abordagem permite que as páginas de destino sejam referenciadas pelo seu nome, definido no arquivo faces-config.xml, o que evita que o código da aplicação tenha que ser alterado se os caminhos das mesmas forem mudados.

A Figura 24 mostra a página com resultados da pesquisa por corridas. Partindo de home.xhtml, o usuário clica no botão Pesquisar, o que faz com que o JSF busque por corridas de acordo com os critérios fornecidos e faça o direcionamento para a página cujo nome é search<. No arquivo faces-config.xml, este nome corresponde à própria página home.xhtml, que é recarregada exibindo os resultados.

Quando é necessário fazer um redirecionamento para uma nova página, isto pode ser feito de duas formas: através de um forward ou de um redirect. Um forward é um redirecionamento feito internamente na aplicação. É fácil perceber visualmente quando ele ocorre apenas olhando para a barra de endereços do seu navegador. Se você foi levado para outra página mas a URL exibida é a mesma, significa que o contêiner realizou a navegação para outro local sem o conhecimento do navegador. Já um redirect é um redirecionamento externo. O contêiner solicita ao navegador que a página seja alterada, logo você pode ver a nova URL diretamente na barra de endereços.

Na prática, a forma de redirecionamento que deve ser utilizada depende do tipo de operação que está sendo realizada no momento. Para funcionalidades que normalmente não alteram o estado da aplicação (como mudanças na base de dados) o forward é utilizado (por exemplo, uma pesquisa por registros). Já quando o usuário realiza uma operação que resulta em uma inserção, exclusão ou alteração de um dado, o melhor caminho é utilizar o redirect logo após a mudança ter sido efetuada. Isto garante que, se o usuário atualizar a página (pressionando F5 em alguns navegadores ou no botão Atualizar), apenas a página que está sendo visualizada será recarregada, e não haverá a re-execução da operação anterior (o que pode deixar o sistema inconsistente, dependendo da situação).

Ao definir as regras de navegação do JSF, é possível determinar se o redirecionamento será feito por forward ou redirect. Por padrão, todos os mapeamentos criados utilizam forward. Para configurar como redirect, é preciso abrir o arquivo faces-config.xml e adicionar a tag redirect dentro de navigation-case. A Listagem 13 mostra a regra de navegação home a partir da página ogin.xhtml, que faz um redirect para home.xhtml.

Listagem 13. Uso do redirect no arquivo faces-config.xml.


<navigation-rule>
      <from-view-id>/login.xhtml</from-view-id>
      <navigation-case>
        <from-outcome>home</from-outcome>
        <to-view-id>/home.xhtml</to-view-id>
        <redirect />
      </navigation-case>
      <navigation-case>
        <from-outcome>create</from-outcome>
        <to-view-id>/cadastrar-usuario.xhtml</to-view-id>
      </navigation-case>
</navigation-rule>

Resultado
da pesquisa de corridas
Figura 24. Resultado da pesquisa de corridas.

Executando a aplicação

Executar a aplicação enquanto ela está sendo criada faz parte do processo de desenvolvimento. No caso específico da aplicação Corrida Favorita, executar significa seguir os seguintes passos:

  1. Gerar o arquivo EAR, composto pelos módulos EJB e web, os quais também devem ser gerados;
  2. Iniciar o servidor de aplicação GlassFish;
  3. Instalar o EAR no servidor;
  4. Criar as tabelas necessárias no banco de dados corrida, a fim de que as entidades possam ser persistidas;
  5. Acessar a URL da aplicação.

É possível notar que existe uma série de tarefas a serem cumpridas e que elas podem tornar o processo de instalação e execução muito demorado, principalmente se ele tiver que ser repetido diversas vezes durante o desenvolvimento.

A boa notícia é que a característica do NetBeans de ser um ambiente integrado possibilita resumir tudo isto a um clique. Quando a aplicação tiver que ser executada, basta utilizar o menu Run > Run Main Project e todos os passos mostrados anteriormente serão realizados automaticamente. Justamente para se beneficiar desta facilidade é que o projeto Corrida-ear, quando criado, foi definido como padrão. Quando ele é executado, o NetBeans é capaz de identificar os módulos e configurações do projeto, gerar todos os arquivos necessários e instalar a aplicação no servidor. Se o servidor de banco de dados (Java DB) e/ou servidor de aplicações (GlassFish) não estiverem executando, o próprio NetBeans os inicializa.

No final do processo, o browser padrão do sistema operacional é aberto com a URL apontando para http://localhost:8080/Corrida. Basta então acessar a URL de login da aplicação para começar a usá-la: http://localhost:8080/Corrida/faces/login.xhtml.

Depois que a aplicação é instalada e o servidor já está executando, o NetBeans proporciona mais uma facilidade: toda vez que uma alteração ocorrer na aplicação, a ferramenta publica as alterações no servidor de forma automática, assim que o arquivo é salvo. Esta é uma grande vantagem, pois possibilita ao desenvolvedor fazer mudanças no código e ver rapidamente o resultado.

Conclusões

Este artigo abordou diversos recursos presentes no NetBeans que auxiliam, e muito, o desenvolvimento de aplicações. Por ser um ambiente completo de desenvolvimento, o NetBeans possui uma série de assistentes, que têm por objetivo acelerar o processo de desenvolvimento e evitar que o desenvolvedor tenha que fazer uma série de configurações e escrever código repetitivo, que não contribui com a lógica de negócio da aplicação em si.

Explorar os recursos do NetBeans, ou de outra IDE que você esteja utilizando, é importante para tornar o desenvolvimento mais produtivo. A versão 7.0, utilizada neste artigo, é a primeira do NetBeans a incluir suporte ao Java 7, ainda não lançado oficialmente. Também traz melhorias no suporte à JPA, novidades na integração com produtos Oracle, como o servidor de aplicações WebLogic e o banco de dados Oracle, entre outras. Enfim, este artigo mostrou diversos recursos importantes deste ambiente, mas muitos outros existem e podem ser utilizados pelos mais variados tipos de aplicação. Cabe aos desenvolvedores irem atrás destas funcionalidades e tentar descobrir outras formas de tornar mais fácil o seu trabalho.

Links

www.netbeans.com
Site oficial do NetBeans.

http://download.oracle.com/javaee/6/tutorial/doc
Java EE 6 Tutorial.

www.oracle.com/technetwork/articles/javaee/jpa-137156.html
Artigo sobre a tecnologia JPA.

www.oracle.com/technetwork/java/javaee/ejb
Site oficial da tecnologia EJB.

www.oracle.com/technetwork/java/javaee/javaserverfaces-139869.html
Site oficial da tecnologia JSF.

www.oracle.com/technetwork/java/javadb
Site oficial do Java DB.

glassfish.java.net
Site oficial do servidor de aplicações GlassFish.

Links Úteis

  • O que é Hibernate?:
    Neste curso você aprenderá o que é o Hibernate, principal framework Java quando o assunto é persistência de dados em bancos de dados relacionais.
  • JPA: Como usar a anotação @Id:
    Nesta documentação você aprenderá a utilizar a anotação @Id para informar qual campo de uma entidade representa a chave primária da respectiva tabela no banco de dados.
  • JSF: Minha primeira aplicação Java WEB:
    Neste curso veremos os passos necessários para a criar a nossa primeira aplicação utilizando essa tecnologia.
  • JPA: Como usar a anotação @Entity:
    Nesta documentação você aprenderá a utilizar a anotação @Entity para informar que uma classe representa uma entidade e que seus objetos devem ser persistidos no banco de dados.

Saiba mais sobre NetBeans ;)

Assine nossa newsletter! =)