O JSF é uma especificação para o desenvolvimento de aplicações Web e, seguindo o padrão Model View Controler (MVC) em Java, essa especificação surgiu como uma alternativa ao Struts, que na época era o principal framework para implementar aplicações nesse padrão de projeto. Sua primeira versão foi disponibilizada em 2004 e em 2013 foi lançada a versão 2.2.

Atualmente existem diversos frameworks para construção de interfaces ricas com o JSFS, entre eles, um dos principais é o PrimeFaces que disponibiliza diversos componentes. Atualmente esse framework está na versão 5 e contém um grande número de componentes de formulários, listagem, menus, entre outros.

Este artigo mostrará como implementar uma aplicação com os frameworks JSF utilizando alguns dos principais componentes do PrimeFaces e mostrará como fazer uma conexão com o banco de dados MySQL. O exemplo criado terá duas páginas: uma para o cadastro de usuários e outra para a listagem dos usuários cadastrados.

Configurando o projeto

Para facilitar a configuração do projeto será utilizado o Maven. Para a criação desse projeto serão necessárias as dependências do conector com o MySQL, as bibliotecas do PrimeFaces e também do JSF. Para a biblioteca do PrimeFaces também é necessário adicionar as informações do repositório desse framework. A Listagem 1 mostra o arquivo pom.xml do projeto criado.


<project xmlns="http://maven.apache.org/POM/4.0.0" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
      http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
     <groupId>com.devmedia</groupId>
     <artifactId>primefaces</artifactId>
     <version>0.0.1</version>
     <packaging>war</packaging>
 
     <dependencies>
          <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.6</version>
                <scope>compile</scope>
          </dependency>
          <dependency>
                <groupId>org.primefaces</groupId>
                <artifactId>primefaces</artifactId>
                <version>5.1</version>
                <scope>compile</scope>
          </dependency>
          <dependency>
                <groupId>org.glassfish</groupId>
                <artifactId>javax.faces</artifactId>
                <version>2.1.13</version>
                <scope>compile</scope>
          </dependency>
     </dependencies>
     <repositories>
          <repository>
                <id>prime-repo</id>
                <name>PrimeFaces Maven Repository</name>
                <url>http://repository.primefaces.org</url>
                <layout>default</layout>
          </repository>
     </repositories>
</project>
Listagem 1. Configurando o projeto com o PrimeFaces 5

Depois de configurar as dependências do projeto é necessário configurar a aplicação para usar o framework JSF: como o projeto é de uma aplicação Web, necessitamos criar o arquivo web.xml. O passo mais importante é configurar o Faces Servlet, que utiliza a classe javax.faces.webapp.FacesServlet. Configure o mapeamento das URL’s que serão tratadas pelo JSF, no caso, todos os endereços que terminarem com *.xhtml. Também foi configurado que caso acontece algum erro na aplicação, a requisição seja redirecionada para a página inicial da aplicação. A Listagem 2 mostra o código do arquivo web.xml.


<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" 
  xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
  http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <display-name>com.devmedia.primefaces</display-name>
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
        <welcome-file>/index.xhtml</welcome-file>
    </welcome-file-list>
    <error-page>
        <exception-type>javax.faces.application.ViewExpiredException
        </exception-type>
        <location>/index.xhtml</location>
    </error-page>
</web-app>
Listagem 2. Configuração do Web.xml do projeto

Criando a aplicação

Depois de todas as configurações realizadas é iniciado o desenvolvimento da aplicação. O primeiro passo é a criação da classe que representara os objetos que serão cadastrados no banco de dados. A Listagem 3 exibe o código da classe Usuario, que é a entidade que será salva no MySQL. Essa entidade tem os atributos id (que é um simples identificador dos objetos), o nome (que representa o nome de usuário), a senha (que é a senha do usuário), a dataDeCadastro (que receberá a data que usuário foi cadastrado no banco de dados) e o campo descrição, que recebera uma breve descrição sobre o usuário criado.


package com.devmedia.model;
 
import java.util.Date;
 
public class Usuario {
     
     private int id;
     private String nome;
     private String senha;
     private Date dataCadastro;
     private String descricao;
     
     public int getId() {
          return id;
     }
     public void setId(int id) {
          this.id = id;
     }
     public String getNome() {
          return nome;
     }
     public void setNome(String nome) {
          this.nome = nome;
     }
     public String getSenha() {
          return senha;
     }
     public void setSenha(String senha) {
          this.senha = senha;
     }
     public Date getDataCadastro() {
          return dataCadastro;
     }
     public void setDataCadastro(Date dataCadastro) {
          this.dataCadastro = dataCadastro;
     }
     public String getDescricao() {
          return descricao;
     }
     public void setDescricao(String descricao) {
          this.descricao = descricao;
     }
 
}
Listagem 3. Classe Usuário

Como a aplicação salvará os dados no banco de dados MySQL, é necessário criar essa tabela no banco de dados e a Listagem 4 mostra o código SQL para a criação desta. As colunas criadas são as mesmas dos atributos da classe Usuário. No desenvolvimento dessa aplicação foi utilizado o banco de dados MySQL, mas qualquer outro banco pode ser utilizado, bastando alterar o pom.xml para criar a dependência do conector de outro banco e alterar a String de conexão com o banco de dados.


CREATE DATABASE usuario;
use usuario;
 
CREATE TABLE usuario (
     id INT PRIMARY KEY,
     nome VARCHAR(30),
     senha VARCHAR(10),
     descricao VARCHAR(50),
     data_cadastro TIMESTAMP
);
Listagem 4. Código SQL para a criação da tabela Usuário

A aplicação criada terá métodos para inserir e para recuperar usuários no banco de dados. A Listagem 5 mostra o código da classe que faz todos os acessos ao banco de dados: o construtor da classe faz a conexão com o banco de dados, passando o nome, o usuário e a senha do banco de dados utilizado. O método closeConnection, simplesmente fecha a conexão com o banco de dados.

O método insertUsuario insere no banco de dados um usuário passado como parâmetro. Para isso, foi criado um PreparedStatement que recebe o SQL que será executado e o número de parâmetros que devem ser passados para a query. Logo depois, esses parâmetros são passados para a query e, em seguida o insert é executado. Se o usuário for cadastrado com sucesso o método retorna true, caso contrário, é criado um log com a mensagem de erro e o método retorna false.

O método listUsuario recupera todos os usuários cadastrados no banco e coloca no retorno do método. O primeiro passo para isso é criar um objeto do tipo Statement e passar como parâmetro o comando SQL da busca. Aconsulta do exemplo é bastante simples e ela retorna todos os usuários cadastrados na tabela usuário.


package com.devmedia.model;
 
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
 
import com.devmedia.model.Usuario;
 
public class Connect {
     Connection con = null;
 
     public Connect() throws SQLException {
 
          try {
                Class.forName("com.mysql.jdbc.Driver");
                System.out.println("Instalou driver");
          } catch (ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
          }
 
          String url = "jdbc:mysql://localhost:3306/usuario";
          String user = "root";
          String password = "eduardo73";
          con = DriverManager.getConnection(url, user, password);
     }
 
     public void closeConnection() throws SQLException {
 
          con.close();
     }
 
     // cadastral no banco um usuario passado como parametro
     public boolean insertUsuario(Usuario usuario) {
 
          Statement st = null;
          ResultSet rs = null;
 
          try {
                st = con.createStatement();
 
                PreparedStatement preparedStatement = con
                    .prepareStatement("insert into usuario
                    (id, nome, senha, descricao, data_cadastro) values(?,?,?,?,?)");
                preparedStatement.setInt(1, usuario.getId());
                preparedStatement.setString(2, usuario.getNome());
                preparedStatement.setString(3, usuario.getSenha());
                preparedStatement.setString(4, "" + usuario.getDescricao());
                preparedStatement.setDate(5, new java.sql.Date(new Date().getTime()));
 
                preparedStatement.execute();
                return true;
          } catch (SQLException ex) {
                Logger lgr = Logger.getLogger(Connect.class.getName());
                lgr.log(Level.SEVERE, ex.getMessage(), ex);
                return false;
 
          }
     }
     
     //lista todos os usuarios cadastrados no banco de dados
     public List<Usuario> listUsuarios() {
 
          ArrayList<Usuario> lista = new ArrayList<Usuario>();
 
          Statement st = null;
          ResultSet rs = null;
 
          try {
                st = con.createStatement();
                String sql = "select * from usuario ";
               rs = st.executeQuery(sql);
 
                while (rs.next()) {
 
                     Usuario usuario = new Usuario();
                     usuario.setId(rs.getInt(1));
                     usuario.setNome(rs.getString(2));
                     usuario.setSenha(rs.getString(3));
                     usuario.setDescricao(rs.getString(4));
                     usuario.setDataCadastro(rs.getDate(5));
                     lista.add(usuario);
                }
 
          } catch (SQLException ex) {
                Logger lgr = Logger.getLogger(Connect.class.getName());
                lgr.log(Level.SEVERE, ex.getMessage(), ex);
 
          } finally {
                try {
                     if (rs != null) {
                          rs.close();
                     }
                     if (st != null) {
                          st.close();
                     }
                     if (con != null) {
                          con.close();
                     }
 
                } catch (SQLException ex) {
                     Logger lgr = Logger.getLogger(Connect.class.getName());
                     lgr.log(Level.WARNING, ex.getMessage(), ex);
                }
          }
          return lista;
     }
}
Listagem 5. Classe de conexão com o banco de dados

A Listagem 6 mostra o código do ManagedBean criado para controlar o cadastro e a listagem dos Usuários. ManagedBean são as classes que conectam o código Java com o código da visão. Para criar uma classe desse tipo é necessário utilizar a anotação @ManagedBean e dizer qual o nome desse ManagedBean: o nome é importante, pois nas telas, para acessar a classe, será utilizado o nome usado nessa anotação.

O primeiro método desse ManagedBean é o método cadastrUsuario que recebe um usuário que foi criado na tela de cadastro. Em seguida é criada uma conexão com o banco de dados e finalmente é chamado o método inserUsuario da classe Connect, que faz a inserção do usuário no banco de dados. Se o cadastro for efetuado com sucesso é retornada uma mensagem de sucesso para o usuário, caso contrário, uma mensagem informando o usuário do erro é enviada.

O método listarUsuarios recuperar todos os usuários que estão cadastrados no banco de dados e retorna para a tela que chamou esse método. No JSF todos os métodos que retornam objetos para a tela devem ter o nome iniciado com get. Ainda no ManagedBean são criados os métodos get e set para o atributo Usuário da classe.


package com.devmedia.managedbeans;
 
import java.sql.SQLException;
import java.util.List;
 
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.context.FacesContext;
 
import com.devmedia.model.Connect;
import com.devmedia.model.Usuario;
 
@ManagedBean(name="UsuarioMB")
public class UsuarioManagedBean {
     
     private Usuario usuario = new Usuario();
     
     public String cadastraUsuario() throws SQLException {
          
                Connect con = new Connect();         
                
                
                if (con.insertUsuario(usuario)) {
                     FacesContext.getCurrentInstance().addMessage(
                      null, new FacesMessage(FacesMessage.SEVERITY_INFO,
                      "Sucesso!", "Usuário cadastrado com sucesso!"));
                } else {
                     FacesContext.getCurrentInstance().addMessage(
                        null, new FacesMessage(FacesMessage.SEVERITY_ERROR,"Erro!", 
                        "Erro no cadastr de usuário!"));
 
                }
                con.closeConnection();
                
                
                
          return "";
     }
     
     public List<Usuario> getUsuarios() throws SQLException {
 
          Connect con = new Connect();
          List<Usuario> listaUsuarios = con.listUsuarios();
     
          return listaUsuarios;
     }
     
     public Usuario getUsuario() {
          return usuario;
     }
     
     public void setUsuario(Usuario usuario) {
          this.usuario = usuario;
     }
}
Listagem 6. Managed Bean para cadastrar e listar Usuários

Criando a tela de listagem

Depois de criados o ManagedBean, é possível criar a tela de cadastro de usuários. Nessa tela existe um componente panelGrid que organiza a tela em uma tabela. Depois, um componente spinner, que é um campo de entrada de dados para números onde será cadastrado o id do usuário. Além disso, existem dois componentes inputText para o cadastro dos campos nome e senha e, por último, existe um componente inputTextarea para cadastrar o campo descrição. A Listagem 7 exibe o código para a criação dessa tela.

Ainda na tela de cadastro existe um botão que é representado pelo componente commandButton. O texto do atributo value indica o texto que aparecerá no botão e o atributo opcional icon indica um ícone para aparecer no botão. O atributo action indica qual o método do ManagedBean que será executado e o atributo update que indica que o componente de exibição de mensagens deve ser atualizado depois de cada cadastro.


<html xmlns="http://www.w3.org/1999/xhtml"
     xmlns:h="http://java.sun.com/jsf/html"
     xmlns:f="http://java.sun.com/jsf/core"
     xmlns:p="http://primefaces.org/ui">
 
<h:head>
 
</h:head>
 
<h:body>
     <h:form>
          <p:messages id="messages" />
          <p:panelGrid columns="2">
                <p:outputLabel for="id" value="ID:" />
                <p:spinner id="id" value="#{UsuarioMB.usuario.id}" />
 
                
                <p:outputLabel for="nome" value="Nome:" />
                <p:inputText id="nome" value="#{UsuarioMB.usuario.nome}" />
 
                
                <p:outputLabel for="senha" value="Senha:" />
                <p:inputText id="senha" value="#{UsuarioMB.usuario.senha}" />
 
                
                <p:outputLabel for="descricao" value="Descrição:" />
                <p:inputTextarea id="descricao"
                     value="#{UsuarioMB.usuario.descricao}" />
 
                <p:commandButton  value="Cadastrar" icon="ui-icon-star" 
                 action="#{UsuarioMB.cadastraUsuario}" update="messages">
                </p:commandButton>
 
          </p:panelGrid>
     </h:form>
</h:body>
</html>
Listagem 7. Tela de cadastro de Usuário

A Figura 1 mostra a tela criada no código da Listagem 7: repare que ele tem um campo para o cadastro de cada atributo da classe Usuário. Acima do formulário é mostrada a mensagem de sucesso, indicando que o cadastro do usuário foi realizado com sucesso.

Tela de cadastro de usuários
Figura 1. Tela de cadastro de usuários

O último passo é a criação da tela de listagem dos usuários e, para isso, é utilizado o componente dataTable do Primefaces que é um componente bastante poderoso e que disponibiliza um grande número de funcionalidades com uma implementação bastante simples. O atributo value indica o método do ManagedBean de onde virão os dados: no caso o método getUsuarios da classe UsuarioManagedBean e o atributo var indica o nome da variável para ser utilizada na recuperação dos dados dos objetos.

Dentro do dataTable são colocadas as colunas (uma para cada atributo dos usuários). O atributo headerText indica o título da coluna, que será renderizada na primeira linha da tabela. Dentro de cada coluna é colocado um outputText com cada um dos atributos. Um componente dataTable do PrimeFaces é transformado em um componente table do HTML. A Listagem 8 mostra o código para a criação da tela de listagem de usuários.


<html xmlns="http://www.w3.org/1999/xhtml"
   xmlns:h="http://java.sun.com/jsf/html"
   xmlns:f="http://java.sun.com/jsf/core"
   xmlns:p="http://primefaces.org/ui">

<h:head>

</h:head>

<h:body>
   <h:form>
        <p:dataTable var="usuario" value="#{UsuarioMB.usuarios}">
              <p:column headerText="Id">
                   <h:outputText value="#{usuario.id}" />
              </p:column>

              <p:column headerText="Nome">
                   <h:outputText value="#{usuario.nome}" />
              </p:column>

              <p:column headerText="Senha">
                   <h:outputText value="#{usuario.senha}" />
              </p:column>

              <p:column headerText="Descrição">
                   <h:outputText value="#{usuario.descricao}" />
              </p:column>
              
              <p:column headerText="Data de Cadastro">
                   <h:outputText value="#{usuario.dataCadastro}" />
              </p:column>               
        </p:dataTable>


   </h:form>
</h:body>
</html>
Listagem 8. Tela de listagem de Usuários

A Figura 2 mostra a tela de listagem de usuários criada na Listagem 8. Cada linha na tabela é um usuário que está cadastrado no banco e cada coluna mostra um atributo da classe usuário. Os dados são exibidos na ordem de retorno do SQL, por isso, caso se queira manter a ordenação por algum campo é necessário inserir a clausula ORDER BY na consulta.

Tela de listagens de usuários
Figura 2. Tela de listagens de usuários

Este artigo mostrou como criar uma aplicação simples com o JavaServer Faces, o PrimeFaces e o MySQL para o cadastro e a listagem de uma entidade. O projeto utilizou a versão mais recente do PrimeFaces, que é hoje um dos principais frameworks para a criação de interfaces ricas do JSF.