Anda di halaman 1dari 32

Agenda em JSF, com CSS, Ajax e MySQL – Parte I

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.

Eu escrevi recentemente um tutorial sobre uso de arquivos de propriedades (Resource


Blundle) cuja a extensão é .properties, aonde vimos o quanto eles podem ser uteis,
principalmente para a internacionalização de aplicativos, em nossa agenda usaremos
uma arquivo de propriedade, chamado mensagens.properties.

Este é o conteúdo do arquivo br.com.nitewing.agenda.mensagens.properties:

# Sample ResourceBundle properties file


Titulo=Agenda com Netbeans,CSS,JSF,Ajax e MySQL
Nome=Nome
Endereco=Endereco
Telefone=Telefone
Bairro=Bairro
Cidade=Cidade
Cep=CEP
Estado=Estado
mensagens.properties

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 class AgendaBean {

private Connection conn;

public void abrirConexao() throws


SQLException,NamingException,ClassNotFoundException{
if(conn !=null) return;
Class.forName("com.mysql.jdbc.Driver");
conn =
DriverManager.getConnection("jdbc:mysql://localhost:3306/agenda","root","
");

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

Agora faremos algumas modificações no arquivo faces-config.xml

<?xml version="1.0" encoding="UTF-8"?>


<!DOCTYPE faces-config PUBLIC "-//Sun Microsystems, Inc.//DTD JavaServer
Faces Config 1.1//EN" "http://java.sun.com/dtd/web-facesconfig_1_1.dtd">
<!-- =========== FULL CONFIGURATION FILE
================================== -->
<faces-config xmlns="http://java.sun.com/JSF/Configuration">
<managed-bean>
<description>
Bean para trazer os dados do MySQL
</description>
<managed-bean-name>agenda</managed-bean-name>
<managed-bean-class>br.com.nitewing.agenda.AgendaBean</managed-bean-
class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
</faces-config>

O seu web.xml deve ficar parecido com o mostrado abaixo se você estiver no
netbeans:

<?xml version="1.0" encoding="UTF-8"?>


<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<context-param>
<param-name>com.sun.faces.verifyObjects</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<param-name>com.sun.faces.validateXml</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>
<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>*.faces</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>
index.jsp
</welcome-file>
</welcome-file-list>
</web-app>

As seções <servlet-mapping> e <welcome-file> são as que merecem atenção e


no arquivo mostrado acima.

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>

O parâmetro url-pattern pode ter os seguintes valores mapeados:


*.jsf , *.faces ou ainda /faces/*

Agora crie um arquivo JSP e chame-o de index.jsp e acrescente o seguinte conteúdo:

<%@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>

Logo após as tags <f:view> e <head> nos utilizamos a tag:


<f:loadBundle basename="br.com.nitewing.agenda.mensagens"
var="msgs"/>
onde informamos que o arquivo que iremos usar se encontra no pacote
br.com.nitewing.agenda e que se chama mensagens (sem o .properties) e declaramos
o item var como msgs, ou seja a partir de agora iremos nos referir ao arquivo como
msgs.
Na linha <h:outputText value="#{msgs.Titulo}"/> nós fazemos referencia ao arquivo
de propriedade quando passamos o valor #{msgs.Titulo} para renderizar o valor do
Titulo.

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:

<h:dataTable value="#{agenda.dados}" var="agenda" border="0"


headerClass="cabecalho" rowClasses="linha1,linha2">

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:

CREATE DATABASE agenda;


use agenda
CREATE TABLE registros(
id int (11) not null autoincrement,
nome varchar(50) not null,
endereco varchar(40),
bairro varchar(25),
cidade varchar(40),
estado char(2),
cep varchar(8),
telefone(11),
primary key(id));

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

Na segunda parte de nosso artigo iremos acrescentar os métodos responsáveis pela


inserção, alteração e atualização de dados e também acrescentaremos os recursos da
tecnologia Ajax com a ferramenta Ajax4Jsf.
Desenvolvendo uma Agenda (CRUD) com JSF - Parte II
Meses atrás eu iniciei um artigo que mostrava como preencher um grid com dados
originados de uma tabela do MySQL
(http://www.devmedia.com.br/articles/viewcomp.asp?comp=6565), mas o tempo
passou e eu havia me esquecido de dar continuidade ao artigo até que recebi alguns
e-mails me perguntando se haveria ou não uma continuação, por isso estou aqui para
dar continuidade, essa nova serie de artigos, o foco do artigo não mudou mas resolvi
retirar o nome da IDE NetBeans do título pois o crud que iremos desenvolver pode
ser feito até no bloco de notas, por isso eu não pretendendo citar recursos específicos
de nenhum IDE.

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.

O Modelo MVC-2 (Model-View-Controller) consiste numa arquitetura para o desenho


de aplicações web de formas complexas e modulares, onde existem três camadas:
· Modelo
· Controlador
· Visão/Apresentação

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.

Figura 1. Estrutura de pacotes

Recomendo que seja criado um novo projeto, mas caso deseje manter o antigo,
aquele que usamos na primeira parte não haverá problema algum.

Vamos começar criando no pacote br.com.nitewing.agenda a classe Contatos.java:

package br.com.nitewing.agenda.model;

public class Contatos {

/** Declaração de Atributos, Observe que so os mesmos campos existente


* Na tabela que criamos no MySQL, os atributos devem ser declarados
privados
*/
private int id;
private String nome;
private String endereco;
private String bairro;
private String cidade;
private String estado;
private String cep;
private String telefone;

public Contatos() {
// Construtor da classe vazio
}

public Contatos(int id, String nome, String endereco, String bairro,


String cidade, String estado, String cep, String telefone) {
//Construtor recebendo parâmetros
this.nome = nome;
this.endereco = endereco;
this.bairro = bairro;
this.cidade = cidade;
this.estado = estado;
this.cep = cep;
this.telefone = telefone;
}
// Getters e Setters

public String getBairro() {


return bairro;
}

public void setBairro(String bairro) {


this.bairro = bairro;
}

public String getCep() {


return cep;
}

public void setCep(String cep) {


this.cep = cep;
}

public String getCidade() {


return cidade;
}

public void setCidade(String cidade) {


this.cidade = cidade;
}

public String getEndereco() {


return endereco;
}

public void setEndereco(String endereco) {


this.endereco = endereco;
}

public String getEstado() {


return estado;
}

public void setEstado(String estado) {


this.estado = estado;
}

public String getNome() {


return nome;
}

public void setNome(String nome) {


this.nome = nome;
}

public String getTelefone() {


return telefone;
}

public void setTelefone(String telefone) {


this.telefone = telefone;
}
}

Agora vamos criar uma interface(*) que chamaremos de InterfaceContatosDAO que


ficará no pacote br.com.nitewing.agenda.dao, onde ficaram as classes responsáveis
pela camada de persistência :

package br.com.nitewing.agenda.dao;

import br.com.nitewing.agenda.model.Contatos;
import java.util.List;

public interface InterfaceContatosDAO {

void atualizar (Contatos contato) throws ContatosDAOException;


void excluir (Contatos contato) throws ContatosDAOException;
void salvar (Contatos contato)throws ContatosDAOException;
List listarTodos()throws ContatosDAOException ;
}

(*) Uma Interface em java é um mecanismo simplificado de implementação de


herança múltipla, possibilitando assim que mais de uma interface determine os
métodos que uma classe herdeira deve implementar. Utilizamos uma Interface para
podermos implementar o Padrão DAO(DATA ACCESS OBJECT), que nos ajuda a
evitarmos ter código JDBC dentro de páginas Web.

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 class ContatosDAOException extends Exception{

public ContatosDAOException() {
}

public ContatosDAOException(String arg) {


super(arg);
}

public ContatosDAOException(Throwable arg) {


super(arg);
}

public ContatosDAOException(String arg,Throwable arg1){


super(arg,arg1);
}
}

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.

Crie em br.com.nitewing.agenda.dao a classe ConnectContatosFactory.java:

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
*
*/

public class ConnectContatosFactory {

public static Connection getConnection() throws ContatosDAOException


{
try {
Class.forName("com.mysql.jdbc.Driver");
return
DriverManager.getConnection("jdbc:mysql://localhost:3306/agenda", "root",
"admin");
} catch (Exception e) {
throw new ContatosDAOException(e.getMessage());
}
}

public static void closeConnection(Connection conn, Statement stmt,


ResultSet rs)
throws ContatosDAOException {
close(conn, stmt, rs);
}

public static void closeConnection(Connection conn, Statement stmt)


throws ContatosDAOException {
close(conn, stmt, null);
}
public static void closeConnection(Connection conn)
throws ContatosDAOException {
close(conn, null, null);
}

private static void close(Connection conn, Statement stmt, ResultSet


rs) throws ContatosDAOException {
try {
if (rs != null) {
rs.close();
}
if (stmt != null) {
stmt.close();
}
if (conn != null) {
conn.close();
}
} catch (Exception e) {
throw new ContatosDAOException(e.getMessage());
}
}
}

A classe ContatosDAO vai herdar os métodos de InterfaceContatosDAO e nós iremos


implementar a lógica necessária para a conexão com o Banco de dados e persistência
de dados. A classe ContatosDAO.java deve ser criada em
br.com.nitewing.agenda.dao.

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;

public class ContatosDAO implements InterfaceContatosDAO {

private Connection conn;

public ContatosDAO() throws ContatosDAOException {


try {
this.conn = ConnectContatosFactory.getConnection();
} catch (Exception e) {
throw new ContatosDAOException("Erro" + ":\n" +
e.getMessage());
}

public void salvar(Contatos contato) throws ContatosDAOException {


PreparedStatement ps = null;
Connection conn = null;
if(contato == null)
throw new ContatosDAOException("O Valor passado não pode ser
lido");
try {
String sql = "insert into
registros(nome,endereco,bairro,cidade,estado,cep,telefone)" +
"values(?,?,?,?,?,?,?)";
conn = this.conn;
ps = conn.prepareStatement(sql);
ps.setString(1, contato.getNome());
ps.setString(2, contato.getEndereco());
ps.setString(3,contato.getBairro());
ps.setString(4, contato.getCidade());
ps.setString(5, contato.getEstado());
ps.setString(6, contato.getCep());
ps.setString(7, contato.getTelefone());
ps.executeUpdate();
} catch (Exception sqle) {
throw new ContatosDAOException("Erro ao inserir dados" + sqle);
}finally{
ConnectContatosFactory.closeConnection(conn, ps);

}
}

public List listarTodos() throws ContatosDAOException {


PreparedStatement ps = null;
Connection conn = null;
ResultSet rs = null;

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

list.add(new Contatos(id, nome, endereco, bairro, cidade,


estado, cep, telefone));

}
return list;

} catch (Exception sqle) {


throw new ContatosDAOException(sqle);
} finally {
ConnectContatosFactory.closeConnection(conn, ps, rs);
}
}

public void atualizar(Contatos contato) throws ContatosDAOException {


throw new UnsupportedOperationException("Not supported yet.");
}

public void excluir(Contatos contato) throws ContatosDAOException {


throw new UnsupportedOperationException("Not supported yet.");
}
}

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:

-- Estrutura da tabela `registros`


--

CREATE TABLE `registros` (


`id` int(11) NOT NULL auto_increment,
`nome` varchar(50) NOT NULL,
`endereco` varchar(40) default NULL,
`bairro` varchar(25) default NULL,
`cidade` varchar(40) default NULL,
`estado` varchar(2) default NULL,
`cep` varchar(8) default NULL,
`telefone` varchar(11) default NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=9 ;

--
-- Extraindo dados da tabela `registros`
--

INSERT INTO `registros` (`id`, `nome`, `endereco`, `bairro`, `cidade`,


`estado`, `cep`, `telefone`) VALUES
(1, 'Rodrigo Cegueta', 'Av La paz', 'Barra', 'Salvador', 'BA',
'40000000', '88562356'),
(2, 'Kleyson Marques', 'Rua dos Pardais', 'Pituba', 'Salvador', 'BA',
'40000000', '98562856'),
(3, 'Simone Pereira', 'Rua dos Vigilantes', 'Liberdade', 'Salvador',
'BA', '40000000', '91162886'),
(4, 'Edson Parasect', 'Alameda Parque J Cesar', 'Pituba', 'Salvador',
'BA', '40000000', '84842189'),

Na terceira parte do artigo iremos implementar a classe ContatosController e adicionar


suporte a JSF (caso você ainda não tenha o feito) e configurá-lo, bem como criar as
telas para listagem e cadastro de contatos.
Desenvolvendo uma Agenda (CRUD) com JSF - Parte III
Agora vamos finalmente colocar o nosso CRUD para funcionar, iniciaremos criando a
classe ContatosController.java que será usada pelo JavaServer Faces, observe que
seus métodos retornam Strings que informam ações solicitadas a aplicação bem como
retorno de ações executadas ou a serem executadas mapeadas no faces-config.xml
como ocorre por exemplo com os métodos novoContato() e create().

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;

public class ContatosController {

private Contatos contato;


private DataModel model;

public String novoContato(){


this.contato = new Contatos();
return "novo";
}

public Contatos getContato(){


return contato;
}

public void setContato(Contatos contato){


this.contato = contato;
}

public DataModel getTodos() throws ContatosDAOException {


InterfaceContatosDAO icdao = new ContatosDAO();
model = new ListDataModel(icdao.listarTodos());
return model;
}

public String create()throws ContatosDAOException {


InterfaceContatosDAO icdao = new ContatosDAO();
icdao.salvar(contato);
return "sucesso_ins";
}
// Aqui acrescentaremos os métodos para Atualização e Exclusão.
}

Usaremos arquivos de propriedades(Resource Bundles) já explicados em artigos


anteriores, crie em: br.com.nitewing.agenda crie o arquivo mensagens.properties:

# To change this template, choose Tools | Templates


# and open the template in the editor.

Titulo=Agenda JSF e MySQL


Id=Codigo
Nome=Nome
Endereco=Endereco
Telefone=Telefone
Bairro=Bairro
Cidade=Cidade
Cep=CEP
Estado=Estado

Criando agora a camada visual de nossa agenda:

Na pasta web (NetBeans) ou WebContent (Eclipse) serão criados os seguintes


arquivos:
· index.jsp
· estilos.css
· inserirContato.jsp
· mostrar.jsp

Este é o código de index.jsp (index.faces):

<%@page contentType="text/html" 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>JSP Page</title>
</head>
<body>
<% response.sendRedirect("mostrar.faces"); %>
</body>
</html

Este é o código de estilos.css:

/*
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;
}

Este é o código de mostrar.jsp (mostrar.faces):

<%@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):

<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>


<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@page contentType="text/html" 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>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>

Em WEB-INF crie o arquivo web.xml (ou altere se ele já existir):

<?xml version="1.0" encoding="UTF-8"?>


<web-app version="2.5" 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-app_2_5.xsd">
<context-param>
<param-name>com.sun.faces.verifyObjects</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<param-name>com.sun.faces.validateXml</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>
<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>*.faces</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>

Em WEB-INF crie o arquivo faces-config.xml :

<?xml version='1.0' encoding='UTF-8'?>

<!-- =========== FULL CONFIGURATION FILE


================================== -->

<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

As Figuras 2 e 3 mostram a execução da aplicação:

Figura 2. Cadastrando um novo contato


Figura 3. Listagem de Contatos

Na próxima parte do artigo iremos implementar os métodos para Exclusão e


Atualização de registros.
JSF – Usando arquivos de propriedades(Resource
Bundle) para internacionalização de aplicativos
Este artigo tem como objetivo mostrar o uso de arquivos .properties (os Resources
Bundles), eles servem pra inúmeras coisas, mas nesse artigo iremos dar um enfoque
maior em seu uso para internacionalização de aplicações em JSF.

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>

Altere o contéudo do arquivo web.xml acrescentando as seguintes linhas:

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

E nele adicionaremos o seguinte conteúdo:

title=Inscrição para Workshop


text=Por favor insira o seu nome e sobrenome e email.
firstNamePrompt=Nome
lastNamePrompt=Sobrenome
emailAddressPrompt=Email
buttonLabel=Inscrever

Ao Executarmos o nosso aplicativo nós nos depararemos com a tela mostrada na


figura1, que é nossa pagina índice:
Figura1

Clique no link Exemplo Mensagens Simples.

E você será levado para o conteúdo da figura2:

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.

Crie o arquivo parametros.jsp e insira o segundo contéudo:

<%@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>

Agora vamos criar o arquivo mensagens2,properties também no pacote recursos.

O conteúdo dele é o mostrado a seguir:

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

Como pode ver no conteúdo de mensagens.properties usamos valores entre cochetes,


para a formar uma frase e com isso evitar escrevermos nomes dos campos
novamente num properties file, usamos isso na pratica no arquivo parametros.jsp:

<h:outputFormat value="#{msgs.text}">
<f:param value="#{msgs.firstName}"/>
<f:param value="#{msgs.lastName}"/>
<f:param value="#{msgs.emailAddress}"/>
</h:outputFormat>

O resultado é mostrado a seguir:


Figura3

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.

Vamos criar arquivos para 4 idiomas : Inglês, Português, Espanhol e Francês;

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 isso é necessário modificar o idioma usado no navegador e reiniciar a pagina


para ver a pagina sendo exibida em outro idioma.

No Firefox use Edit Preferences e configure conforme mostrados nas figuras e


mostradas abaixo:
Figura4

Em Languages(Linguagem) clique em Choose(escolher).


Figura5

Para priorizar um idioma clique na seta move up(mover para cima) ou move
down(mover para baixo).

Caso você use Netscape é bem parecido, no IE eu não me lembro e no Opera é só ir


em Tools >> Preferences >> General >> Languages e escolher o idioma desejado.

O resultado é mostrado:

Figura6
Figura7

Figura8
Figura9