Escolar Documentos
Profissional Documentos
Cultura Documentos
Neste artigo vamos criar uma agenda usando JSF, CSS,Ajax,MySQL e como IDE vou
usar Netbeans 5.5 mas isso não impede que você use o Eclipse, provavelmente
alguem vai dizer:”Outro exemplo de agenda!”, bom esse existentem poucos tutorias
em português que retratem o uso de tabelas em JSF, uso de CSS com JSF, dentre
outras coisas que serão mostradas no decorrer do artigo.
Vamos criar o Bean AgendaBean, aplicações em JSF usam bean java(managed bean)
para controlar ações que serão requisitadas pela aplicação, para isso crie uma classe
java com o nome de AgendaBean no pacote br.com.nitewing.agenda, com o seguinte
contéudo:
/*
* AgendaBean.java
* Created on 9 de Setembro de 2007, 11:24
* @author claudiosvirgens@nitewing
*/
package br.com.nitewing.agenda;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javax.naming.NamingException;
import javax.servlet.jsp.jstl.sql.Result;
import javax.servlet.jsp.jstl.sql.ResultSupport;
import
org.apache.taglibs.standard.tag.common.core.NullAttributeException;
}
public Result getDados() throws SQLException, NamingException,
ClassNotFoundException{
try{
abrirConexao();
Statement stmt = conn.createStatement();
ResultSet result = stmt.executeQuery("SELECT * FROM
registros");
return ResultSupport.toResult(result);
}finally{
fecharConexao();
}
}
public void fecharConexao() throws SQLException{
if(conn == null)return;
conn.close();
conn = null;
}
}
Como vocês podem ter percebido no código de AgendaBean uma instância da conexão
só é criada se não existir uma instância do mesmo, o que impede que seja criada
inúmeras instâncias do objeto de conexão.
Vamos exibir para um usuário uma tabela contendo os registros existentes na base de
dados, e para melhorar a aparência da tabela iremos usar css.
Crie um arquivo .css contendo a folha de estilos que usaremos no nosso artigo. o
nome do arquivo é estilo.css, ele devera ser salvo numa pasta chamada css, na
raiz(root) do seu projeto web(web,webcontent), e seu conteúdo é mostrado a seguir:
/*
Document : estilo.css
Created on : 09/09/2007, 14:19
Author : claudiosvirgens@nitewing
Description: Folha de estilo agenda em netbeans
*/
.cabecalho {
font-family: Arial, Helvetica, sans-serif;
font-weight: bold;
font-size: 14px;
color: white;
background-color: #3D77C0;
text-align: center;
}
.linha1 {
font-family: Arial, Helvetica, sans-serif;
font-size: 12px;
color: black;
background-color: beige;
text-indent: 11px;
}
.linha2 {
font-family: Arial, Helvetica, sans-serif;
font-size: 12px;
color: black;
background-color: #E1ECF7;
text-indent: 11px;
}
O seu web.xml deve ficar parecido com o mostrado abaixo se você estiver no
netbeans:
Caso esteja usando o Eclipse certifique que o conteúdo deles estejam como mostrado
abaixo:
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.faces</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>
index.jsp
</welcome-file>
</welcome-file-list>
<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<f:view>
<head>
<f:loadBundle basename="br.com.nitewing.agenda.mensagens"
var="msgs"/>
<meta http-equiv="Content-Type" content="text/html;
charset=UTF-8">
<title><h:outputText value="#{msgs.Titulo}"/></title>
<link rel="stylesheet" type="text/css"
href="./css/estilo.css">
</head>
<body>
<div align="center">
<h:form>
<h:form>
<h3><h:outputText value="#{msgs.Titulo}"/></h3>
<h:dataTable value="#{agenda.dados}" var="agenda"
border="0"
headerClass="cabecalho"
rowClasses="linha1,linha2">
<h:column>
<f:facet name="header">
<h:outputText
value="#{msgs.Nome}" />
</f:facet>
<h:outputText value="#{agenda.nome}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText
value="#{msgs.Endereco}" />
</f:facet>
<h:outputText
value="#{agenda.endereco}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText
value="#{msgs.Bairro}" />
</f:facet>
<h:outputText value="#{agenda.bairro}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText
value="#{msgs.Cidade}" />
</f:facet>
<h:outputText value="#{agenda.cidade}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText
value="#{msgs.Estado}" />
</f:facet>
<h:outputText value="#{agenda.estado}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText
value="#{msgs.Cep}" />
</f:facet>
<h:outputText value="#{agenda.cep}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText
value="#{msgs.Telefone}" />
</f:facet>
<h:outputText
value="#{agenda.telefone}"/>
</h:column>
</h:dataTable>
</h:form>
</h:form>
</div>
</body>
</f:view>
</html>
Na linha a seguir nós usamos a tag <h:dataTable> para para pegar os dados
retornados pelo bean agenda, declaramos a variável agenda e ainda mapeamos as
classes existentes no arquivo estilo.css com os objetos headerClass e rowClasses:
Agora vamos compilar e executar a primeira parte do nosso artigo, excute o nosso
seu editor preferido e o resultado deverá ser uma tela como a mostrada na Figura
Figura1
Não faz parte do escopo deste artigo ensinar o usuário a usar o MySQL mas segue
anexo os comandos necessários para criação do banco de dados:
Para inserir registros na tabela utilize o camando INSERT como mostrado abaixo:
INSERT INTO registros (nome,endereco,bairro,cidade,estado,cep,telefone)
WHERE ('Alexandre Soneca', 'Av La paz','Pituba','Ba', 'Salvador',
'40000000','88562356');
execute o comando INSERT com outros valores a para termos uma quantidade melhor
de
CRUD significa: CREATE, READ, UPDATE AND DELETE (algo como: “Criar,Ler,Atualizar
e Apagar”), em nosso artigo o CRUD será a agenda que começamos a desenvolver na
primeira parte do artigo.
Nessa segunda parte do artigo iremos re-estruturar nossa agenda obedecendo aos
padrões MVC-2 e DAO e com isso adquirir os benefícios da orientação objetos.
Crie o projeto, caso esteja utilizando uma IDE, selecione a opção de Projeto
JavaServer Faces. Agora precisaremos criar pacotes para que tenhamos as separações
das camadas, conforme a Figura1.
Recomendo que seja criado um novo projeto, mas caso deseje manter o antigo,
aquele que usamos na primeira parte não haverá problema algum.
package br.com.nitewing.agenda.model;
public Contatos() {
// Construtor da classe vazio
}
package br.com.nitewing.agenda.dao;
import br.com.nitewing.agenda.model.Contatos;
import java.util.List;
Vamos criar também uma classe chamada ContatosDAOException que vai permitir
que geremos exceções personalizadas, ela estende a java.lang.Exception, alem disso
criaremos a seguir a classe ConnectContatosFactory onde faremos uso da classe
ContatosDAOException:
package br.com.nitewing.agenda.dao;
public ContatosDAOException() {
}
A próxima classe que criaremos será utilizada para a fábrica de conexões. Ela cria
uma conexão e retorna o resultado para quem a chamar, observe que ela faz uso de
ContatosDAOException toda vez que ocorre um erro e for preciso lançar uma exceção.
Além disso, ela possui métodos de CloseConnection para fechar a conexão, o
Statement e o ResultSet.
package br.com.nitewing.agenda.dao;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
/*
* Esta classe sera a nossa fabrica de conexões. Ela cria a conexão
* e retorna o resultado para quem a chamar, obsever que ela faz uso
* de ContatosDAOException toda vez que ocorre um erro, alem disse ela
possui
* métodos de CloseConnection para fechar a conexão, o Statement e o
ResultSet
*
*/
ContatosDAO.java:
package br.com.nitewing.agenda.dao;
import br.com.nitewing.agenda.model.Contatos;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
}
}
try {
conn = this.conn;
ps = conn.prepareStatement("select id,nome,endereco,bairro,"
+
"cidade,estado,cep,telefone from registros");
rs = ps.executeQuery();
List list = new ArrayList();
while (rs.next()) {
int id = rs.getInt(1);
String nome = rs.getString(2);
String endereco = rs.getString(3);
String bairro = rs.getString(4);
String cidade = rs.getString(5);
String estado = rs.getString(6);
String cep = rs.getString(7);
String telefone = rs.getString(8);
}
return list;
Foge do escopo do artigo ensinar como usar o MySQL, assim sendo você deverá saber
como criar uma base dados com o nome de agenda e criar a tabela registros. A
seguir, apresento o código para criação da tabela registros:
--
-- Extraindo dados da tabela `registros`
--
ContatosController.java:
package br.com.nitewing.agenda.control;
import br.com.nitewing.agenda.dao.ContatosDAO;
import br.com.nitewing.agenda.dao.ContatosDAOException;
import br.com.nitewing.agenda.dao.InterfaceContatosDAO;
import br.com.nitewing.agenda.model.Contatos;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-
8">
<title>JSP Page</title>
</head>
<body>
<% response.sendRedirect("mostrar.faces"); %>
</body>
</html
/*
Document : estilo.css
Created on : 09/09/2007, 14:19
Description: Folha de estilo agenda em netbeans
*/
.cabecalho {
font-family: Arial, Helvetica, sans-serif;
font-weight: bold;
font-size: 14px;
color: white;
background-color: #3D77C0;
text-align: center;
}
.linha1 {
font-family: Arial, Helvetica, sans-serif;
font-size: 14px;
color: black;
background-color: beige;
text-indent: 11px;
}
.linha2 {
font-family: Arial, Helvetica, sans-serif;
font-size: 14px;
color: black;
background-color: #E1ECF7;
text-indent: 11px;
}
<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<html>
<f:view>
<head>
<f:loadBundle basename="br.com.nitewing.agenda.mensagens"
var="msgs" />
<meta http-equiv="Content-Type" content="text/html;
charset=UTF-8">
<title><h:outputText value="#{msgs.Titulo}"/></title>
<link rel="stylesheet" type="text/css" href="estilo.css">
</head>
<body>
<h:form>
<h3><h:outputText value="#{msgs.Titulo}"/></h3>
<h:dataTable value="#{contatos.todos}" var="agenda"
border="0" headerClass="cabecalho"
rowClasses="linha1,linha2">
<h:column>
<f:facet name="header">
<h:outputText
value="#{msgs.Id}" />
</f:facet>
<h:outputText value="#{agenda.id}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText
value="#{msgs.Nome}" />
</f:facet>
<h:outputText value="#{agenda.nome}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText
value="#{msgs.Endereco}" />
</f:facet>
<h:outputText value="#{agenda.endereco}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText
value="#{msgs.Bairro}" />
</f:facet>
<h:outputText value="#{agenda.bairro}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText
value="#{msgs.Cidade}" />
</f:facet>
<h:outputText value="#{agenda.cidade}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText
value="#{msgs.Estado}" />
</f:facet>
<h:outputText value="#{agenda.estado}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText
value="#{msgs.Cep}" />
</f:facet>
<h:outputText value="#{agenda.cep}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText
value="#{msgs.Telefone}" />
</f:facet>
<h:outputText value="#{agenda.telefone}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText
value="Excluir" />
</f:facet>
<h:commandLink value="Excluir" />
</h:column>
</h:dataTable>
<br />
<h:commandLink action="#{contatos.novoContato}"
value="Novo Contato" />
</h:form>
</body>
</f:view>
</html>
inserirContato.jsp (.faces):
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-
8">
<title>Inserindo Novos Contatos</title>
</head>
<body>
<h2>Adicionar Novo Contato</h2>
<f:view>
<h:form id="cadastro">
<h:panelGrid columns="2">
<h:outputText value="Nome:"/>
<h:inputText size="25" id="nome"
value="#{contatos.contato.nome}" />
<h:outputText value="Endereço:"/>
<h:inputText size="25" id="endereco"
value="#{contatos.contato.endereco}"/>
<h:outputText value="Bairro:"/>
<h:inputText size="15" id="bairro"
value="#{contatos.contato.bairro}"/>
<h:outputText value="Cidade:"/>
<h:inputText size="15" id="cidade"
value="#{contatos.contato.cidade}" />
<h:outputText value="Estado:"/>
<h:inputText size="2" id="estado"
value="#{contatos.contato.estado}" />
<h:outputText value="CEP:"/>
<h:inputText size="8" id="cep" value="#{contatos.contato.cep}" />
<h:outputText value="Telefone:"/>
<h:inputText size="15" id="telefone"
value="#{contatos.contato.telefone}"/>
</h:panelGrid>
<h:commandButton value="Cadastrar" action="#{contatos.create}" />
<h:commandButton value="Limpar" type="reset" />
<h:commandButton value="Cancelar" action="mostrar" />
</h:form>
</f:view>
</body>
</html>
<faces-config version="1.2"
xmlns="http://java.sun.com/xml/ns/javaee"
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-facesconfig_1_2.xsd">
<managed-bean>
<description>
O Bean ContatosController
</description>
<managed-bean-name>contatos</managed-bean-name>
<managed-bean-
class>br.com.nitewing.agenda.control.ContatosController
</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
<navigation-rule>
<navigation-case>
<description>
Mostrando todos contatos
</description>
<from-outcome>mostrar</from-outcome>
<to-view-id>/mostrar.jsp</to-view-id>
</navigation-case>
</navigation-rule>
<navigation-rule>
<display-name>mostrar</display-name>
<from-view-id>/mostrar.jsp</from-view-id>
<navigation-case>
<description>
Adicionando um novo contato pela
pagina mostrar.jsp(mostrar.faces)
</description>
<from-outcome>novo</from-outcome>
<to-view-id>/inserirContato.jsp</to-view-id>
</navigation-case>
</navigation-rule>
<navigation-rule>
<from-view-id>/inserirContato.jsp</from-view-id>
<navigation-case>
<description>
Regra de navegação caso ocorra sucesso na inserção do
livro observe que o view outcome tem como valor strings que representam
ações existentes tanto controller quanto nos formulários.
</description>
<from-outcome>sucesso_ins</from-outcome>
<to-view-id>/mostrar.jsp</to-view-id>
</navigation-case>
</navigation-rule>
</faces-config>
Figura 1. Representação gráfica do faces-config.xml
index.jsp
<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-
8">
<title>JSF - Usando Properties Files</title>
</head>
<body>
<h1>JSF - Usando Properties Files</h1>
<br/>
<li><a href="./simples.jsf">Exemplo Mensagens Simples</a></li>
<li><a href="./parametros.jsf">Exemplo Mensagens
Parametrizadas</a></li>
<li><a href="./parametros.jsf">Internacionalização</a></li>
</body>
</html>
simples.jsp
<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>
<%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
<%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-
8">
<title>Mensagens Simples</title>
</head>
<body>
<f:view>
<h1>JSF - Usando Properties Files</h1>
<f:loadBundle basename="recursos.mensagens" var="msgs"/>
<h2><h:outputText value="#{msgs.title}"/></h2>
<BR>
<h:outputText value="#{msgs.text}"/>
<P>
<h:form>
<table border="0" cellspacing="2" cellpadding="2">
<tbody>
<tr>
<td> <h:outputText
value="#{msgs.firstNamePrompt}"/>:</td>
<td><h:inputText /></td>
</tr>
<tr>
<td><h:outputText
value="#{msgs.lastNamePrompt}"/>:</td>
<td> <h:inputText /></td>
</tr>
<tr>
<td><h:outputText
value="#{msgs.emailAddressPrompt}"/>:</td>
<td><h:inputText /></td>
</tr>
<tr>
<td><h:commandButton
value="#{msgs.buttonLabel}"/></td>
<td></td>
</tr>
</tbody>
</table>
</h:form>
</f:view>
</body>
</html>
<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>*.jsf</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>
index.jsp
</welcome-file>
</welcome-file-list>
Agora vamos criar um pacote chamado recursos e dentro do pacote recursos vamos
criar um arquivo com extensão .properties, vamos chama-lo de
mensagens.properties.
Figura2
Como pode ver o nosso formulário foi composto com os campos existentes no arquivo
mensagens.properties.
Pode parecer meio inútil mas vamos prosseguir e você começara a ver utilidades pro
exemplo a seguir.
<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>
<%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
<%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Mensagens Parametrizadas</title>
</head>
<body>
<div align="center">
<f:view locale="#{facesContext.externalContext.request.locale}">
<f:loadBundle basename="recursos.mensagens2" var="msgs"/>
<h1><h:outputText value="#{msgs.title}"/></h1>
<h:outputFormat value="#{msgs.text}">
<f:param value="#{msgs.firstName}"/>
<f:param value="#{msgs.lastName}"/>
<f:param value="#{msgs.emailAddress}"/>
</h:outputFormat>
</div>
<P>
<h:form>
<table border="0" cellspacing="2" cellpadding="2" align="center">
<tbody>
<tr>
<td> <h:outputFormat value="#{msgs.prompt}">
<f:param value="#{msgs.firstName}"/>
</h:outputFormat>:</td>
<td><h:inputText /></td>
</tr>
<tr>
<td><h:outputFormat value="#{msgs.prompt}">
<f:param value="#{msgs.lastName}"/>
</h:outputFormat>:</td>
<td><h:inputText /></td>
</tr>
<tr>
<td><h:outputFormat value="#{msgs.prompt}">
<f:param value="#{msgs.emailAddress}"/>
</h:outputFormat>:</td>
<td><h:inputText /></td>
</tr>
<tr>
<td><h:commandButton
value="#{msgs.buttonLabel}" />
</td>
<td></td>
</tr>
</tbody>
</table>
</h:form>
</f:view>
</body>
</html>
title=WorkShop Registration
firstName=first name
lastName=last name
emailAddress=email address
text=Please enter your {0}, {1}, and {2}.
prompt=Enter {0}
buttonLabel=Register Me
<h:outputFormat value="#{msgs.text}">
<f:param value="#{msgs.firstName}"/>
<f:param value="#{msgs.lastName}"/>
<f:param value="#{msgs.emailAddress}"/>
</h:outputFormat>
Agora vamos ver o uso dos Properties Files para Internacionalização de aplicativos,
graças a estes arquivos é possível fazer uma aplicação que atenda a varios usuários
de nacionalidades diferentes sem necessáriamente ter que criar uma versão da
aplicação para cada idioma.
mensagens2_en.properties
# Sample ResourceBundle properties file
title=Registration
firstName=first name
lastName=last name
emailAddress=email address
text=Please enter your {0}, {1}, and {2}.
prompt=Enter {0}
buttonLabel=Register Me
mensagens2_pt.properties
# Sample ResourceBundle properties file
title=Cadastro
firstName=nome
lastName=Sobrenome
emailAddress=endereço de email
text=Informe por favor seu {0}, {1}, e {2}.
prompt=Informe {0}
buttonLabel=Enviar
mensagens2_es.properties
# Sample ResourceBundle properties file
title=Registro
firstName=primer nombre
lastName=apellido
emailAddress=dirección de email
text=Incorpore por favor su {0}, {1}, y {2}.
prompt=Incorpore {0}
buttonLabel=Coloqúeme
mensagens2_fr.properties
# Sample ResourceBundle properties file
title=Enregistrement
firstName=prénom
lastName=nom
emailAddress=adresse électronique
text=Merci de entrer votre {0}, {1}, et {2}.
prompt=Entrez votre {0}
buttonLabel=Enregistrez moi
A rodar a aplicação ela irá verificar qual a localidade do Browser usado pelo visitante e
ira carregar a pagina de acordo com o idioma setado, caso não encontre ela usa o
idioma padrão contido no arquivo mensagens2,properties.
Para priorizar um idioma clique na seta move up(mover para cima) ou move
down(mover para baixo).
O resultado é mostrado:
Figura6
Figura7
Figura8
Figura9