Mostrando postagens com marcador JSF. Mostrar todas as postagens
Mostrando postagens com marcador JSF. Mostrar todas as postagens

11 de agosto de 2008

JavaServer Faces: Facilitando o Desenvolvimento Web - Palestra É Dia de Java 2007


Produtividade com JavaServer Faces

From: eduardo.bregaida, 9 minutes ago





Palestra Ministrada na Universidade de Santa Barbara do Oeste


SlideShare Link

JavaServer Faces Produtividade em Desenvolvimento - JustJava 2007


JavaServer Faces Produtividade em Desenvolvimento

From: eduardo.bregaida, 1 hour ago





Palestra ministrada no JustJava 2007


SlideShare Link

JSF e outras tecnologias Java Web - IMES.java

Estou postando a palestra que ministrei no evento IMES.java (USCS.java), o evento infelizmente foi marcado por um dia chuvoso.
Todas as palestras foram ótimas, logo estaremos disponibilizando as outras palestras no site do evento.








SlideShare Link

21 de agosto de 2007

Tutorial Facelets

Olá a todos, este é o primeiro tutorial que aborda o assunto de Facelets aqui no JavaWora. Acredito que todos que gostam de Java Server Faces estão super acostumados com a tecnologia, mas aqueles que usavam Struts e html puro, uma vez no mundo do JSF, uma das principais dificuldades (contornáveis é claro) era compreender a lógica das tags que de certa forma se distância do HTML convencional, o que eu até discordo em partes, afinal acho que um <html:text/> não se aproxima tanto de <input type=”text”/>, mas tudo bem, sabemos que da mesma forma aprender Struts não é uma tarefa das mais fáceis. Enfim vamos ao que interessa.

Um dos pontos que mais desagrada empresas que vão utilizar JSF é a distância do HTML convencional, portanto uma dificuldade de que designers possam efetuar atualizações, manutenções e coisas do gênero em uma página, pois bem, para “simplificar” toda essa dificuldade, foi desenvolvido uma tecnologia chamada de Facelets, aqueles que já viram o Tapestry verão muitas semelhanças, apontada como uma das inspiradoras para o Facelets.
No Tapestry utilizávamos a palavra chave jwcid (Java Web Component Id), para que o Framework substituísse aquele conteúdo por um componente desejado, e eis que apresento a palavra mágica do Facelets: jsfc (Java Server Faces Component). Não se engane isso não é uma cópia descarada, mas uma inspiração do primo de JSF, mas qual a mágica de tal palavrinha no caso de Facelets?O que ganhamos com isso?

Imagine o seguinte, você recebe a pagina HTML do designer, e você tem que alterar tudo aquilo, porque é tudo diferente do que você usa. Seus problemas acabaram! Basta você por uma palavrinha mágica em componentes, por exemplo:

<input type=”text”/>
Adicione:

<input type=”text” jsfc=”h:inputText” value=”#{cadastro.nome}”/>

Mágico, não acham? Um reaproveitamento de código maravilhoso e louvável. Outro ponto que nos interessa em reaproveitamento é a criação de um template, tiles é um bom framework mas deixa a desejar em alguns pontos. Com Facelets podemos definir um template declarativamente, de forma que a página sabe em qual template está inserida, reduzindo o esforço para descobrir seus componentes.
Para criar um template apenas devemos assinar os componentes da página por meio de <ui:insert name="menu"> dentre as tags do facelets, caso queiramos inserir o conteúdo de um html naquele tag na página que define o template, utilizamos então: <ui:include src="/templates/menu.xhtml"/>. No momento em que vamos utilizar um determinado template numa página, basta declará-lo: <ui:composition template="/templates/common.xhtml">, e inserir o que estmos sobrescrevendo por meio de <ui:define name="body">conteúdo</ui:define> no espaço delimitado pelas tags em conteúdo. Mais uma vez, simples, muito simples. O Facelets ainda possui componentização, Ájax integrado, dentre outras funcionalidades, mas vamos nos focar no core aqui, que é templates e reaproveitamento de html original.
O suporte de IDES ao Facelets ainda é fraco, o NetBeans possui um suporte, já no universo eclipse, temos o Exadel e agora o novíssimo Red Hat Developer Studio, os melhores na minha opinião. O exemplo deste tutorial foi desenvolvido com a implementação da Sun e no tomcat 5.5, no tomcat 6 algumas mudanças são necessárias. Os jars necessários são:

  • common-annotations.jar
  • commons-beanutils.jar
  • commons-collections.jar
  • commons-digester.jar
  • commons-logging.jar
  • el-api.jar
  • el-ri.jar
  • jsf-api.jar
  • jsf-facelets.jar
  • jsf-impl.jar
  • jsf-tlds.jar
  • jstl.jar
  • standard.jar





O web-xml necessário está na Figura 1. Criaremos três Classes para nossa lógica, são elas:

Listagem 1 – Login.java

package br.com.facelets.bean;
public class Login {
private String userName;
private String senha;
public Login() {
}
//sets e gets omitidos
@Override
public int hashCode() {
final int PRIME = 31;
int result = 1;
result = PRIME * result + ((senha == null) ? 0 : senha.hashCode());
result = PRIME * result + ((userName == null) ? 0 : userName.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final Login other = (Login) obj;
if (senha == null) {
if (other.senha != null)
return false;
} else if (!senha.equals(other.senha))
return false;
if (userName == null) {
if (other.userName != null)
return false;
} else if (!userName.equals(other.userName))
return false;
return true;
}
}



Listagem 2 – Cadastro.java

package br.com.facelets.bean;
import javax.faces.context.FacesContext;
import br.com.facelets.business.CadastroSaver;
public class Cadastro {
private String nome;
private String senha;
private String userName;
public String getLogin() {
return userName;
}
public void setLogin(String login) {
this.userName = login;
}
//sets e gets omitidos
public String salvar(){
Login login = new Login();
login.setUserName(userName);
login.setSenha(senha);
CadastroSaver.salvar(login, this);
return "ok";
}
public String logar(){
Login login = new Login();
login.setUserName(userName);
login.setSenha(senha);
Cadastro cadastro = CadastroSaver.busca(login);
if(cadastro!=null){
FacesContext.getCurrentInstance().getExternalContext()
.getSessionMap().put("user", cadastro);
return "ok";
}else{
FacesContext.getCurrentInstance().getExternalContext()
.getRequestMap().put("erro", "login/senha inválidos");
return "erro";
}
}
}



Listagem 3 – CadastroSaver.java

package br.com.facelets.business;
import java.util.Hashtable;
import br.com.facelets.bean.Cadastro;
import br.com.facelets.bean.Login;
public class CadastroSaver {
private static final Hashtable saver = new Hashtable();
public static void salvar(Login login,Cadastro cadastro){
saver.put(login, cadastro);
}
public static Cadastro busca(Login login){
return saver.get(login);
}
}


E agora o faces-config e as páginas propriamente ditas.
Listagem 4- faces-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<faces-config version="1.2" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xi="http://www.w3.org/2001/XInclude"
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>
<managed-bean-name>cadastro</managed-bean-name>
<managed-bean-class>br.com.facelets.bean.Cadastro</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>nome</property-name>
<property-class>java.lang.String</property-class>
<value/>
</managed-property>
<managed-property>
<property-name>login</property-name>
<property-class>java.lang.String</property-class>
<value/>
</managed-property>
</managed-bean>
<navigation-rule>
<from-view-id>/pages/dados.xhtml</from-view-id>
<navigation-case>
<from-outcome>ok</from-outcome>
<to-view-id>/pages/inputname.xhtml</to-view-id>
<redirect/>
</navigation-case>
</navigation-rule>
<navigation-rule>
<from-view-id>/pages/login.xhtml</from-view-id>
<navigation-case>
<from-outcome>ok</from-outcome>
<to-view-id>/pages/greeting.xhtml</to-view-id>
<redirect/>
</navigation-case>
<navigation-case>
<from-outcome>erro</from-outcome>
<to-view-id>/pages/login.xhtml</to-view-id>
</navigation-case>
</navigation-rule>
<application>
<view-handler>com.sun.facelets.FaceletViewHandler</view-handler>
<resource-bundle>
<base-name>resources</base-name>
<var>msg</var>
</resource-bundle>
<message-bundle>resources</message-bundle>
</application>
</faces-config>





Listagem 5 – menu.xhtml

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<body bgcolor="#ffffff">
<table style="border:1px solid #CAD6E0" align="center" cellpadding="0" cellspacing="0" border="0">
<tbody>
<tr>
<td colspan="2" valign="bottom" height="1" bgcolor="#CAD6E0">
<table>
<tr>
<td>
<a href="dados.jsf">Incluir dados</a>
</td>
</tr>
<tr>
<td>
<a href="login.jsf">Login</a>
</td>
</tr>
</table>
</td>
</tr>
</tbody>
</table>
</body>
</html>



Listagem 6 – common.xhtml

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<span jsfc="f:loadBundle" basename="resources" var="msg"/>
<head>
<title>
<ui:insert name="pageTitle">JavaWora</ui:insert>
</title>
<style type="text/css">
body {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 14px;
}
.header {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 18px;
}
.bottom {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 9px;
text-align: center;
vertical-align: middle;
color: #8E969D;
}
</style>
</head>
<body bgcolor="#ffffff">
<table style="border:1px solid #CAD6E0" align="center" cellpadding="0" cellspacing="0" border="0" width="400">
<tbody>
<tr>
<td class="header" align="center" valign="middle" width="100%" bgcolor="#E4EBEB">
<ui:insert name="pageHeader">JavaWora Facelets</ui:insert>
</td>
</tr>
<tr>
<td height="1" width="100%" bgcolor="#CAD6E0"></td>
</tr>
<tr>
<td width="100%">
<table width="100%" style="height:150px" align="left" cellpadding="0"
cellspacing="0" border="0">
<tbody>
<tr>
<td align="center" width="10%" valign="middle">
<ui:insert name="menu">
<ui:include src="/templates/menu.xhtml"/>
</ui:insert>
</td>
<td align="center" width="75%" valign="middle">
<ui:insert name="body">Page Body</ui:insert>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td colspan="2" valign="bottom" height="1" width="100%" bgcolor="#CAD6E0"></td>
</tr>
</tbody>
</table>
</body>
</html>



Listagem 7 – cadastro.xhtml

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
template="/templates/common.xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Cadastro</title>
</head>
<ui:define name="body">
<form jsfc="h:form" id="cadastro">
<table>
<tr>
<td>Nome*:</td>
<td>
<input type="text" jsfc="h:inputText" value="#{cadastro.nome}" id="nome" label="#{msg.lbl.nome}" required="true" requiredMessage="#{msg.erroRequired}"/>
</td>
<td><h:message for="nome" id="erroNome"></h:message> </td>
</tr>
<tr>
<td>login*:</td>
<td>
<input type="text" jsfc="h:inputText" value="#{cadastro.login}" id="login" label="#{msg.lbl.login}" required="true" requiredMessage="#{msg.erroRequired}"/>
</td>
<td><h:message for="login" id="erroLogin"></h:message> </td>
</tr>
<tr>
<td>senha*:</td>
<td>
<input type="text" jsfc="h:inputSecret" value="#{cadastro.senha}" id="senha" label="${msg.lbl.senha}" required="true" requiredMessage="#{msg.erroRequired}"/>
</td>
<td><h:message for="senha" id="erroSenha"></h:message> </td>
</tr>
<tr>
<td>Estado Civil:</td>
<td>
<select jsfc="h:selectOneMenu" value="#{cadastro.idEstado}" id="eCivil" label="#{msg.lbl.estadoCivil}">
<option jsfc="f:selectItem" itemValue="1" itemLabel="Casado"></option>
<option jsfc="f:selectItem" itemValue="2" itemLabel="Solteiro"></option>
<option jsfc="f:selectItem" itemValue="3" itemLabel="Divorciado"></option>
</select>
</td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="submit" value="Salvar" jsfc="h:commandButton" action="#{cadastro.salvar}"/>
</td>
</tr>
</table>
</form>
</ui:define>
</ui:composition>



Listagem 8 – inputname.xhtml

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:c="http://java.sun.com/jstl/core">
<ui:composition template="/templates/common.xhtml">
<ui:define name="pageTitle">
Bem Vindo
</ui:define>
<ui:define name="pageHeader">
Home
</ui:define>
<ui:define name="body">
${msg.prompt}
</ui:define>
</ui:composition>
</html>



Listagem 9 – greeting.xhtml

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<f:loadBundle basename="resources" var="msg" />
<ui:composition template="/templates/common.xhtml">
<ui:define name="body">
#{msg.greeting} <span jsfc="h:outputLabel" value="#{sessionScope.user.nome}"/>!
</ui:define>
</ui:composition>
</html>



Listagem 10 – login.xhtml



<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
template="/templates/common.xhtml">
<ui:define name="body">
#{erro}
<form jsfc="h:form" id="login">
<table>
<tr>
<td>Login:</td><td><input jsfc="h:inputText" value="#{cadastro.login}" type="text"/></td>
</tr>
<tr>
<td>Senha:</td><td><input jsfc="h:inputSecret" value="#{cadastro.senha}" type="password"/></td>
</tr>
<tr>
<td colspan="2" align="center">
<input jsfc="h:commandButton" action="#{cadastro.logar}" type="submit" value="OK"/>
</td>
</tr>
</table>
</form>
</ui:define>
</ui:composition>



Experimente abrir a pagina de login no firefox, ie, ou qualquer ferramenta WYSIWYG (acho q é isso) e veja que os parametros estão lá, até a pagina, mas como isso é possível? Ora como eu disse trata-se de uma página simples xhml, a propósito podemos trabalhar com xhtml diretamente em facelets, ou mesmo jsps, mas xhtml é mais legal. A aplicação consiste em efetuar um cadastro e logo após um login para verificar se os dados foram armazenados.
Agora vamos as curiosidades. Conforme observado no web.xml, há dois listeners registrados, eles são necessários para o Tomcat 5.5, pois o compilador utilizado no facelets não é o Jasper que vêm nele, mas um próprio.
No web.xml observe a sentença:


<context-param>
<param-name>facelets.DEVELOPMENT</param-name>
<param-value>true</param-value>
</context-param>

Cause um erro em uma página e observe o que ocorre, figura 2:






O compilador descreve o erro e lhe auxilia com a arvores de componentes gerada e os dados do que estavam presentes. Legal né! Pois agora troque a sentença para false. Você verá que o erro agora é apresentado como na figura 3. Bonito não?!







Obrigado e até mais!

18 de julho de 2007

MyFaces 1.2 é lançado

A famosa implementação de JSF da Apache foi liberada. O release Myfaces 1.2, cuja data oficial de lançamento é 17 de julho, implementa a JSR-252. Já homologado pela Sun, o projeto passou em 100% dos testes.
A api pode ser obtida no site: http://myfaces.apache.org/download.html e seu release notes pode ser visto em: https://issues.apache.org/jira/secure/ReleaseNote.jspa?projectId=10600&styleName=Html&version=12312576.
Dentre as novidades está a "louvável" correção de alguns bugs, além de seguir agora a nova (nem tão nova assim) especificação de Java Server Faces.
Contudo ainda não há confirmação de compatibilidade com o Tomahawk, Trinidad e outros projetos de componentes extendidos da Apache, resta a oportunidade de alguém testar e relatar nesse blog se a informação se confirma.

4 de julho de 2007

Tutorial JSF - Parte 2

Bom, terminando o tutorial vou colocar o JSF da página de login e as classes da parte de cadastro com um CRUD completo.

Criada as classes falta criar os devidos JSP das mesmas, então vou montar um JSP bem fácil utilizando libs JSF

Linhas importantes:

Este comando acima além de dizer q o campo é obrigatório (required="true"), no value passamos a EL (Expression Language) com a ação que queremos executar ( value="#{autenticador.login}").

Esta linha nos exibe uma mensagem no qual defini em um properties.
Neste botão eu disparo a ação de pegar os dados do usuário que está logando e validando.

A tela irá ficar mais ou menos assim:

Mas como ligar os Managed Beans na tela?
Pelo faces-config.xml
Ficaria assim:


Em XML:



managed-bean
managed-bean-name autenticador
managed-beanclass br.com.imes.acesso.Acesso
managed-bean-scope session
Todo o Managed-bean tem que ter um nome, uma classe (o Bean lógico), e o scope é para ver se o Bean vai ficar em Sessão ou requisisão.
navigation-rule
from-view-id /login.jsp
navigation-case
from-outcome usuario
to-view-id /agenda.jsp
Aqui eu defino as regras de navegação do meu Bean, para onde vai se a saída for usuário, caso contrário ele mantém o estado e fica na mesma página exibindo a mensagem de erro.
application
message-bundle messages
locale-config
default-locale pt_BR
Nessa área apenas estou dizendo a linguagem nativa que uso e definindo o messages.properties
E pronto, pode rodar que seu login estará perfeitamente validando.
Agora vou colocar as classes e as páginas dos Dados da nossa agenda.
Classe Dados.java
package br.com.imes.dados;
import java.util.Calendar;
import java.util.GregorianCalendar;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import br.com.imes.acesso.Acesso;
@Entity
         public class Dados {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String nome;
private String telefoneResidencial;
private String telefoneComercial;
private String celular;
private String nextel;
private String email;
private String observacao;
@Temporal(TemporalType.DATE)
private Calendar data = new GregorianCalendar();
public Calendar getData() {
return data;
}
public void setData(Calendar data) {
this.data = data;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getCelular() {
return celular;
}
public void setCelular(String celular) {
this.celular = celular;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getNextel() {
return nextel;
}
public void setNextel(String nextel) {
this.nextel = nextel;
}
public String getObservacao() {
return observacao;
}
public void setObservacao(String observacao) {
this.observacao = observacao;
}
public String getTelefoneComercial() {
return telefoneComercial;
}
public void setTelefoneComercial(String telefoneComercial) {
this.telefoneComercial = telefoneComercial;
}
public String getTelefoneResidencial() {
return telefoneResidencial;
}
public void setTelefoneResidencial(String telefoneResidencial) {
this.telefoneResidencial = telefoneResidencial;
}
}
Aqui possui a relação com Hibernate e os getters e setters.
Classe DadosHandler.java

package br.com.imes.dadoshandler;
import java.util.List;
import javax.faces.component.UIComponent;
import javax.faces.component.UIParameter;
import javax.faces.event.ActionEvent;
import org.hibernate.Session;
import br.com.imes.dados.Dados;
import br.com.imes.dao.DAO;
import br.com.imes.hibernate.hibernateutil.HibernateUtil;
public class DadosHandler {
private Dados dados = new Dados();
public Dados getDados() {
return dados;
}
public void setDados(Dados dados) {
this.dados = dados;
}
public void salvarDados() {
Session session = HibernateUtil.getCurrentSession();
System.out.println("Qual id aqui? " + this.dados.getId());
if (dados.getId() == null) {
DAO dao = new DAO(session, Dados.class);
System.out.println("Qual id aqui? " + this.dados.getId());
dao.save(this.dados);
} else {
session.merge(this.dados);
}
this.dados = new Dados();
}
public void deletarDados() {
Session session = HibernateUtil.getCurrentSession();
DAO dao = new DAO(session, Dados.class);
if (dados.getId() == null) {
session.merge(this.dados);
} else {
dao.deleta(this.dados);
}
this.dados = new Dados();
}
//Tabela JSF
public List getDados2() {
Session session = HibernateUtil.getCurrentSession();
DAO dao = new DAO(session, Dados.class);
return dao.list();
}
//Evento do JSF
public void carregaDados(ActionEvent event) {
UIComponent comandLink = event.getComponent();
UIParameter parameter = (UIParameter) comandLink
.findComponent("editId");
Long id = (Long) parameter.getValue();
Session session = HibernateUtil.getCurrentSession();
DAO dao = new DAO(session, Dados.class);
this.dados = dao.load(id);
System.out.println("Qual id aqui2? " + this.dados.getId());
}
//Ajax
public List suggest(String buscaNome) {
Session session = HibernateUtil.getCurrentSession();
DAO dao = new DAO(session, Dados.class);
mandaListaSuggest();
return dao.buscaNome(buscaNome);
}
}
Aqui é onde o programa vai tratar os dados com aquele DAO Genérico criado. Fiz uma pequena brincadeira com AJAX para criar um auto-complete. No Evento do JSF é para pegar o id do usuário para carrega-lo na tabela que só aparecerá quando a mesma estiver montada.
Bom, o suggest ainda não faz nada além de auto-completar, a idéia seria gerar uma pesquisa, mas não implementei, senão deixaria complexo demais para um exemplo simples em JSF, só queria mostrar como é simples implementar Ajax em páginas JSF.
O Amateras não reconhece CSS dentro de tags JSF, logo vocês só verão a tela bonitinha quando rodar do Browser.
Infelizmente o Blogger.com não permite que eu coloque códigos XML, nem HTML na página, não sei porque mas ele tenta rodar, também não deixa nas cores e identização, logo aconselho a baixar o download e testar o código.
Qualquer dúvida estarei disponível, caso eu continue implementando este pequeno projeto eu vou postando ele aqui.
A idéia é que JSF é um padrão da Sun e uma poderosa e rápida ferramenta para se trabalhar.
O Exemplo dispinível com minha palestra no JustJava que está mais completa que este código e com menu está disponível no site, você pode fazer o download do código e testar.

21 de junho de 2007

Tutorial JSF - Parte 1

Bom Vamos começar, desculpe a demora, na verdade vou atualizar se der toda semana, faculdade, provas e etc me atrapalham um pouco.

Bom não vou entrar em detalhe sobre Hibernate, no Blog do Alberto ele está detalhando muito bem isso.

A idéia será focar melhor em JavaServer Faces.




Bom, vamos imaginar algo bem simples de fazer, uma agenda Web, no qual o propósito será:

Incluir, Excluir e Alterar meus contatos.

Poderíamos ter feito de várias maneiras, por exemplo, JDBC puro, Struts, Spring, Struts 2, e etc.




Mas por que JSF e JPA? Porque são padrões da SUN e está documentado em JSR´s, sem perigo de por exemplo: "O grupo que desenvolvia o framework XPTO não faz mais, perdi tudo e vamos ter que migrar".




O que vamos precisar para esse primeiro exemplo?

Baixe o JDK do site da Sun.

Baixe o EasyEclipse ou o IDE que você goste mais.

Baixe o webcontainer, o TomCat é muito bom para esse pequeno exemplo.

Baixe o MyFaces Tomahawk.
Baixe o Hibernate: - Hibernate Core, Hibernate Annotations e o Hibernate EntityManager.

Baixe o MySQL.

Descompacte os arquivos no seu ClassPath do projeto e vamos começar.




Como utilizaremos Hibernate e JPA não precisamos gerar as tabelas na mão dentro do Banco, vamos montar um esquema com anotações que o Hibernate crie.




XML

Vamos começar com o hibernate.cfg.xml



















Básicamente ninguém cria do zero isso, normalmente todo mundo tem esse padrão +/- aí de cima, vou detalhar um pouco do q cada linha faz para ficar bem claro.

property name="hibernate.dialect"
org.hibernate.dialect.MySQLDialect

property name="hibernate.connection.url"

jdbc:mysql://localhost/teste

property name="hibernate.connection.driver_class"
com.mysql.jdbc.Driver

property name="hibernate.connection.username"
root

property name="hibernate.connection.password"
root

Essas linhas servem para:

-Dizer qual o meu banco de dado, caso mude é só alterar o Dialect.

- A String de conexão e url

- O Meu usuário e senha do Banco




property name="hibernate.c3p0.min_size" 1 /property
property name="hibernate.c3p0.max_size" 10 /property
property name="hibernate.c3p0.maxIdleTime" 200 /property
property name="hibernate.c3p0.timeout" 180 /property
property name="hibernate.c3p0.idle_test_period" 100 /property
property name="hibernate.c3p0.max-statements" 50 /property




Para meu Pool de conexões, ou seja, para delimitar alguns limites estou usando o C3PO que já está nos Jar´s do Hibernate.

Estou usando Cache level 2 para manter alguns objetos em chache (não era preciso), é algo bem legal que o Hibernate possui.







mapping class="br.com.caelum.acesso.Acesso"/
mapping class="br.com.caelum.dados.Dados"/
mapping class="br.com.caelum.fornecedor.Fornecedor"/
mapping class="br.com.caelum.contapagar.ContaPagar"/

Aqui estou mapeando as minhas classes que serão entidades no Banco.







CLASSES




Para nosso sistema, devemos criar uma tela de Login e senha antes de entrar na Agenda, isto por mera segurança, você não quer que seu "irmão pentelho" fique mexendo nos seus contatos, quer?

// Login e acesso ao sistema

package br.com.imes.acesso;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

import org.hibernate.Session;

import br.com.imes.acessodao.AcessoDAO;
import br.com.imes.hibernate.hibernateutil.HibernateUtil;

/**
* @author Eduardo Bregaida
*
*/

@Entity
public class Acesso {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
int id;

private String login;

private String senha;

private boolean administrador;

public boolean isAdministrador() {
return administrador;
}

public void setAdministrador(boolean administrador) {
this.administrador = administrador;
}

public String getLogin() {
return login;
}

public void setLogin(String login) {
this.login = login;
}

public String getSenha() {
return senha;
}

public void setSenha(String senha) {
this.senha = senha;
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String logar() {
Session session = HibernateUtil.openSession();
AcessoDAO acessoDAO = new AcessoDAO(session);
return acessoDAO.verificaAutenticacao(this);
}

public void salvar() {
Session session = HibernateUtil.openSession();
AcessoDAO acessoDAO = new AcessoDAO(session);
acessoDAO.salvaUsuario(this);
}

public void deletar() {
Session session = HibernateUtil.openSession();
AcessoDAO acessoDAO = new AcessoDAO(session);
acessoDAO.excluiUsuario(this);
}


}

Para que conhecer Hibernate e/ ou JPA sabe muito bem que tem muitas anotações bem legais, vou explicar as da classe Acesso:

@Entity: aqui estou dizendo, olha sou uma entidade do Banco, vou gerar as tabelas.

@Id : o id é OBRIGATÓRIO quando você diz que uma classes é Entity

@GeneratedValue(strategy = GenerationType.IDENTITY): esta anotação é para dizer que o campo Id é auto-numeração do seu Banco de Dados.







Basicamente até aqui nada mais era do que pura JPA, mas porque então o Hibernate?
@Entity
public class Acesso {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
int id;

private String login;

private String senha;

private boolean administrador;

public boolean isAdministrador() {
return administrador;
}

public void setAdministrador(boolean administrador) {
this.administrador = administrador;
}

public String getLogin() {
return login;
}

public void setLogin(String login) {
this.login = login;
}

public String getSenha() {
return senha;
}

public void setSenha(String senha) {
this.senha = senha;
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}
}







Porque eu utilizo uma Sessão e alguns tipos de pesquisa que só o Hibernate possui, tais como: Critéria e HQL.



public String logar() {
Session session = HibernateUtil.openSession();
AcessoDAO acessoDAO = new AcessoDAO(session);
return acessoDAO.verificaAutenticacao(this);
}

public void salvar() {
Session session = HibernateUtil.openSession();
AcessoDAO acessoDAO = new AcessoDAO(session);
acessoDAO.salvaUsuario(this);
}

public void deletar() {
Session session = HibernateUtil.openSession();
AcessoDAO acessoDAO = new AcessoDAO(session);
acessoDAO.excluiUsuario(this);
}







Vamos ver a classe AcessoDAO para entender aqueles metodos da minha classe de Beans acesso:


package br.com.imes.acessodao;

import org.apache.log4j.Logger;
import org.hibernate.Query;
import org.hibernate.Session;

import br.com.imes.acesso.Acesso;

public class AcessoDAO {

private Session session;

private Logger logger = Logger.getLogger(Acesso.class);

public AcessoDAO(Session session) {
logger.info("Construtor" + session);
this.session = session;

}

/**
* @verifica se o usuário está autorizado para logar no sistema
*/
@SuppressWarnings("unchecked")
public String verificaAutenticacao(Acesso acesso) {
logger.info("HQL" + acesso.getLogin());

Query query = session
.createQuery("select acesso from Acesso as acesso where acesso.login = :login and acesso.senha = :senha");
query.setParameter("senha", acesso.getSenha());
query.setParameter("login", acesso.getLogin());

Acesso acesso2 = (Acesso) query.uniqueResult();

if (acesso2 == null) {
return "erro";
} else {
/*if (acesso2.isAdministrador()){
return "administrador";
}else*/
return "usuario";
}

}

/**
* @verifica salva um novo usuário no sistema
*/
public void salvaUsuario(Acesso acesso) {
session.saveOrUpdate(acesso);
}

/**
* @verifica exclui um usuário no sistema
*/
public void excluiUsuario(Acesso acesso) {
session.delete(acesso);
}


@SuppressWarnings("unchecked")

public Acesso selecionaUsuario(Acesso acesso) {
// TODO Auto-generated method stub
return (Acesso) session.load(Acesso.class, acesso.getLogin());
}
}




Estes são meus métodos no DAO, nada mais são do que métodos de pesquisa, exclusão, alteração, inclusão e etc.




São tratados na minha SessionFilter no qual eu trato todos meus objetos em Sessão, para abrir a sessão foi criado um HibernateUtil onde eu também declaro minhas anotações e crio a minha sessionFactory:




HibernateUtil



package br.com.imes.hibernate.hibernateutil;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;

/**
* @author Eduardo Bregaida
*
*/
public class HibernateUtil {
private static ThreadLocal sessions;

private static SessionFactory sessionFactory;
static {
sessionFactory = new AnnotationConfiguration().configure()
.buildSessionFactory();
sessions= new ThreadLocal();
}

public static Session openSession() {
return sessionFactory.openSession();
}

public static Session getCurrentSession() {
if (sessions.get() == null) {
sessions.set(openSession());
}
return sessions.get();
}

public static void closeCurrentSession() {
getCurrentSession().close();
sessions.set(null);
}
}

HibernateSessionFilter


package br.com.imes.hibernate.sessionfilter;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import br.com.imes.hibernate.hibernateutil.HibernateUtil;

/**
* @author Eduardo Bregaida
*
*/
public class HibernateSessionFilter implements Filter {
public void doFilter(ServletRequest servletRequest,
ServletResponse servletResponse, FilterChain filterChain) throws ServletException {
try {
HibernateUtil.getCurrentSession().beginTransaction();//é obrigado estar
filterChain.doFilter(servletRequest, servletResponse);
HibernateUtil.getCurrentSession().getTransaction().commit();
} catch (Exception e) {
HibernateUtil.getCurrentSession().getTransaction().rollback();
throw new ServletException(e);
} finally {
HibernateUtil.closeCurrentSession();
}

}

public void destroy() {
// TODO Auto-generated method stub

}

public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub

}
}

Aqui na HibernateSessionFilter exatamente eu fecho a transação e dou um commit ou rollback nos dados, também fecho a Sessão atual.

Existem muitas implementações para a configurar a sessionFactory, eu gosto particularmente deste pois é muito fácil de ver o que ela esta fazendo e aonde.

Mostrada a sessionFactory e a sessionFilter vamos para os DAO´s:

Este é a primeira parte do sisteminha, vamos ver se consigo mostrar como ligo isso na camada visual e vamos criar também a área de Dados do nosso sistema onde ocorrerá os cadastros de nossa agenda.

Até logo...