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>
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>
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;
}
}
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
);
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;
}
}
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;
}
}
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>
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.

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>
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.

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.