Postado por:
Fonte: http://javawora.blogspot.com/search/label/JEE
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.
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:
|
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”> 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. <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!