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

agenda com netbeans e jsf ok legal Agenda-Em-JSF

Embed Size (px)

Citation preview

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 fileTitulo=Agenda com Netbeans,CSS,JSF,Ajax e MySQLNome=NomeEndereco=EnderecoTelefone=TelefoneBairro=BairroCidade=CidadeCep=CEPEstado=Estadomensagens.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.cssCreated on : 09/09/2007, 14:19Author : claudiosvirgens@nitewingDescription: 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 agendaCREATE 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 MySQLId=CodigoNome=NomeEndereco=Endereco

Telefone=TelefoneBairro=BairroCidade=CidadeCep=CEPEstado=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.cssCreated on : 09/09/2007, 14:19Description: 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 Workshoptext=Por favor insira o seu nome e sobrenome e email.firstNamePrompt=NomelastNamePrompt=SobrenomeemailAddressPrompt=EmailbuttonLabel=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 RegistrationfirstName=first namelastName=last nameemailAddress=email addresstext=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 filetitle=RegistrationfirstName=first namelastName=last nameemailAddress=email addresstext=Please enter your {0}, {1}, and {2}.prompt=Enter {0}buttonLabel=Register Me mensagens2_pt.properties# Sample ResourceBundle properties filetitle=CadastrofirstName=nomelastName=SobrenomeemailAddress=endereço de emailtext=Informe por favor seu {0}, {1}, e {2}.prompt=Informe {0}buttonLabel=Enviar mensagens2_es.properties# Sample ResourceBundle properties filetitle=RegistrofirstName=primer nombrelastName=apellidoemailAddress=dirección de emailtext=Incorpore por favor su {0}, {1}, y {2}.prompt=Incorpore {0}buttonLabel=Coloqúeme mensagens2_fr.properties# Sample ResourceBundle properties filetitle=EnregistrementfirstName=prénomlastName=nomemailAddress=adresse électroniquetext=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