Tutorial Facelets

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.

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&#8221;
xmlns:xi=”http://www.w3.org/2001/XInclude&#8221;
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance&#8221; xsi:schemaLocation=”http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd”&gt;
<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”&gt;
<html xmlns=”http://www.w3.org/1999/xhtml&#8221;
xmlns:ui=”http://java.sun.com/jsf/facelets&#8221;
xmlns:h=”http://java.sun.com/jsf/html&#8221;
xmlns:f=”http://java.sun.com/jsf/core”&gt;
<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”&gt;
<html xmlns=”http://www.w3.org/1999/xhtml&#8221;
xmlns:ui=”http://java.sun.com/jsf/facelets&#8221;
xmlns:h=”http://java.sun.com/jsf/html&#8221;
xmlns:f=”http://java.sun.com/jsf/core”&gt;
<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”&gt;
<ui:composition xmlns=”http://www.w3.org/1999/xhtml&#8221;
xmlns:ui=”http://java.sun.com/jsf/facelets&#8221;
xmlns:h=”http://java.sun.com/jsf/html&#8221;
xmlns:f=”http://java.sun.com/jsf/core&#8221;
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”&gt;
<html xmlns=”http://www.w3.org/1999/xhtml&#8221;
xmlns:ui=”http://java.sun.com/jsf/facelets&#8221;
xmlns:h=”http://java.sun.com/jsf/html&#8221;
xmlns:f=”http://java.sun.com/jsf/core&#8221;
xmlns:c=”http://java.sun.com/jstl/core”&gt;
<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”&gt;
<html xmlns=”http://www.w3.org/1999/xhtml&#8221;
xmlns:ui=”http://java.sun.com/jsf/facelets&#8221;
xmlns:h=”http://java.sun.com/jsf/html&#8221;
xmlns:f=”http://java.sun.com/jsf/core”&gt;
<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”&gt;
<ui:composition xmlns=”http://www.w3.org/1999/xhtml&#8221;
xmlns:ui=”http://java.sun.com/jsf/facelets&#8221;
xmlns:h=”http://java.sun.com/jsf/html&#8221;
xmlns:f=”http://java.sun.com/jsf/core&#8221;
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!

Anúncios

Criar um pool de conexões no Apache Tomcat

Fonte: http://www.antoniopassos.pro.br/blog/?p=88

1)Configurando o pool de conexões…

No diretório META-INF da aplicação, crie um arquivo “context.xml” com o seguinte conteúdo…

<?xml version=”1.0″ encoding=”UTF-8″?>
<Context auth=”Container”>
<Resource
name=”jdbc/bd_teste”
type=”javax.sql.DataSource”
url=”jdbc:mckoi://localhost:59999/”
driverClassName=”com.mckoi.JDBCDriver”
username=”admin”
password=”123456″
maxActive=”100″
maxIdle=”20″/>
</Context>

Significado de cada atributo usado no arquivo “context.xml“…

  • auth –> Atribui ao Apache Tomcat a responsabilidade de gerenciar a abertura e o fechamento das conexões
  • name –> Nome dado ao pool de conexões. Deve obedecer o formato JNDIATENÇÃO: O NOME DADO AO POOL DEVERÁ SER O MESMO USADO NO ARQUIVO WEB.XML DA APLICAÇÃO.
  • type –> Especifica o tipo como sendo DataSource
  • url –> Especifica a localização do banco de dados. Deve obedecer o formato URL JDBC
  • driverClassName –> Nome da classe do driver JDBC do banco de dados
  • username –> Nome do usuário do BD
  • password –> Senha do usuário do BD
  • maxActive –> Número máximo de conexões ativas no pool
  • maxIdle –> Número máximo de conexões inativas no pool
  • maxWait –> Tempo máximo de espera por uma conexão, em milissegundos

2)Registrando o pool no aplicativo…

No arquivo “web.xml” da aplicação, insira as linhas abaixo…

<resource-ref>
<res-ref-name>
jdbc/bd_teste
</res-ref-name>
<res-type>
javax.sql.DataSource
</res-type>
<res-auth>
Container
</res-auth>
</resource-ref>

ATENÇÃO: O valor em “<res-ref-name>” deve corresponder ao nome dado ao pool de conexões no arquivo “context.xml”. No caso a “jdbc/bd_teste”.

3)Testando o pool..

3.1) Crie uma classe “ServiceLocator.java” com o seguinte conteúdo…

import java.sql.Connection;
import javax.naming.InitialContext;
import javax.sql.DataSource;

public class ServiceLocator {

public static Connection getConexao(String JNDINome) throws Exception {
Connection con = null;

// Obtém a raiz da hierarquia de nomes
InitialContext contexto = new InitialContext();

// Obtém a origem dos dados
DataSource ds = (DataSource)contexto.lookup(“java:comp/env/” + JNDINome);

// Obtém uma conexão
con = ds.getConnection();

// Retorna a conexão
return con;
}
}

3.2) Crie um servlet, que use a classe ServiceLocator acima para obter uma conexão do pool…

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ServletExemplo extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {

private static final String JNDINome = “jdbc/bd_teste”;

public ServletExemplo() {
super();
}

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType(“text/html”);
PrintWriter out = response.getWriter();
out.println(“<h1>Filmes cadastrados</h1>”);

Connection con = null;
try {
con = ServiceLocator.getConexao(JNDINome);
} catch (Exception e) {
e.printStackTrace();
}

String sql = “SELECT * FROM filmes”;
PreparedStatement stmt;
try {
stmt = con.prepareStatement(sql);
ResultSet rs = stmt.executeQuery();
while (rs.next()){
out.println(“Código -> ” + rs.getInt(1) + ” Título -> ” + rs.getString(2));
}
} catch (SQLException e) {
e.printStackTrace();
}
}

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}

<!–
google_ad_client = “pub-9909948656853681”;
google_ad_output = “textlink”;
google_ad_format = “ref_text”;
google_cpa_choice = “CAAQmbj2_gEaCNYZLJsrWhfIKL264YcBMAA”;
google_ad_channel = “9871635485”;
//–>

Entendendo o serialVersionUID

Por Paulo Silveira em 01/04/2008 –

Fonte: http://blog.caelum.com.br/2008/04/01/entendendo-o-serialversionuid/

O serialVersionUID é uma dúvida constante entre muitos desenvolvedores. Afinal, quando e para que exatamente usá-lo? Devo gerar um número aleatório bem grande, ou um número qualquer? Essas perguntas são comuns, e ao desenvolvedor experiente é necessário conhecer a fundo esse detalhe do processo de serialização do Java.

Quando um objeto é serializado no Java, essa sequência de bytes, além de conter seus atributos de instância não transientes, carrega consigo um número que indentifica a “versão” da classe que foi usada durante o processo. Esse é o chamado serialVersionUID, ou seja, o indentificador de versão de serialização de uma classe. Esse número é utilizado para saber se o objeto que estamos recuperando é de uma versão “compatível” com a versão da classe que foi utilizada quando serializamos o objeto: em outras palavras, os arquivos .class não precisam ser necessariamente os mesmos para que o processo de serialização ocorra com sucesso.

Por exemplo, considere a seguinte classe Usuario:

package br.com.caelum;

public class Usuario implements Serializable {
  private String login;
}

Essa classe possui o serialVersionUID igual a 2806421523585360625L. Esse número não é aleatório! Ele é um hash (SHA) calculado em cima dos nomes dos seus atributos, e assinaturas dos métodos em uma ordem bem definida pela especificação do processo de serialização. E como eu sei esse número? O JDK vem com a ferramenta serialver, que implementa esse mesmo hash:

serialver br.com.caelum.Usuario

Se o serialVersionUID utilizado durante a serialização não bater exatamente com o serialVersionUID da classe que está sendo usada para recuperar essa informação, uma exception é lançada: java.io.InvalidClassException.

Por exemplo, se adicionarmos um novo atributo na nossa classe Usuario:

public class Usuario implements Serializable {
  private String login;
  private String senha;
}

Agora teremos o serialVersionUID valendo 416295346730660862L. Caso você serialize um Usuario com a primeira classe aqui definida, e tentar recuperar essa informação usando essa nova versão de classe, receberemos a conhecida java.io.InvalidClassException. Esse é o comportamente que em muitos casos queremos, mas algumas vezes fazemos pequenas modificações na classe as quais percebemos que não impactarão no processo de serialização, e precisamos manter compatibilidade com a versão antiga daquela classe. Para isso, basta definirmos explicitamente qual é o nosso serialVersionUID, e no caso de querer manter compatibilidade com a classe Usuario anterior, vamos utilizar o valor de serialVersionUID que seria gerado pela JVM: 2806421523585360625L. O código ficaria:

public class Usuario implements Serializable {
  private static final long serialVersionUID = 2806421523585360625L;
  private String login;
  private String senha;
}

Às vezes recebemos um warning do Eclipse, e ele pede para que seja definido o serialVersionUID da classe em questão. Isso ocorre porque você implementa Serializable ou uma de suas mães a implementa. O Eclipse então te abre três opções: utilizar o @SurpressWarnings para você assumir o risco, usar um valor default, ou usar o valor gerado. O gerador de UIDs do Eclipse é exatamente o mesmo gerador utilizado pelo Java SE para criar os UIDs padrão! Reforçando, esse número não é um número aleatório!

serialVersionUIDQuando alguém esquece de manter o mesmo serialVersionUID para duas versões compatíveis de uma classe, podemos ter problemas em usar diferentes versões do software que são teoricamente compatíveis. Isso muitas vezes acontece em servidores de aplicação, e se seu cliente esta desatualizado em relação a versão dos jars necessários pelo servidor, podemos ter alguns InvalidClassExceptions que poderiam ser facilmente evitados se o serialVersionUID tivesse sido corretamente aplicado. Claro que algumas outras vezes as versões realmente não são compatíveis e a exception procede.

Esse grave problema pode acontecer mesmo usando classes do Java SE entre diferentes versões, como é o caso da classe java.text.AttributedCharacterIterator.Attribute (utilizada pela java.awt.Font). Do Java 1.3 para o Java 1.4 essa classe foi levemente alterada, e o serialVersionUID gerado pelo algoritmo da JVM desta classe mudou de -1514471214376796190L para -9142742483513960612L. Quando alguém serializava uma java.awt.Font em uma versão não podia desserializa-la em outra, sendo que as versões tecnicamente são compatíveis: a não definição explícita do serialVersionUID gerou um bug no Java SE. Como isto foi resolvido? Definiram o serialVersionUID como -1514471214376796190L, que é o valor que seria gerado pela JVM na versão anterior da classe.

Como então devemos proceder para escolher um serialVersionUID apropriado? É muito simples: se essa classe está nascendo neste momento, você pode se dar ao luxo de utilizar um serialVersionUID, como por exemplo:

public class Usuario implements Serializable {
  private static final serialVersionUID = 1L;
  private String login;
}

Porém se você está definindo o serialVersionUID de uma classe já em produção, e sabe que a mudança que está fazendo é compatível com a versão anterior, você deve utilizar o serialVersionUID que seria gerado pela JVM na primeira versão, como foi o caso aqui quando adicionamos o atributo senha na classe Usuario, e também foi o caso da correção do bug da classe java.text.AttributedCharacterIterator.Attribute. Quando você fizer uma alteração onde percebe que o cliente precisará de atualização das classes envolvidas, basta definir um serialVersionUID diferente dos anteriormente utilizados.

Para completar, implementar uma interface que não define métodos (Serializable) e ser forçado a escrever um atributo sem um contrato mais burocrático é um tanto estranho em uma linguagem como o Java. Sem dúvida, se esse mecanismo todo tivesse sido inventado já com a existência de anotações, Serializable seria uma anotação e version um atributo dela, talvez obrigatório, criando algo como @Serializable(version=12345L). Boas serializações e invocações remotas!

Criptografia em 3 linhas

Fonte: http://jchrisos.wordpress.com/2008/03/26/criptografia-em-3-linhas/

Olá pessoal!!!

Todos sabem como é importante uma aplicação ter segurança, tanto ela sendo para web, desktop, dispositivos móveis, etc. Por isso existem vários conceitos de segurança de software e um deles é a criptografia. Para saber mais sobre criptografia clique aqui e segurança da informação clique aqui. Neste post mostrarei um exemplo de como criptografar uma senha utilizando o algoritmo MD5.

Eu já vi muitos tutoriais ensinando como criptografar informações, mas todos faziam uma implementação horrível, utilizavam arrays de bytes que depois cada elemento era tranformado em um valor hexadecimal e mais outras coisas. A classe no final tinha 20 a 30 linhas, lembrando até aqueles tutoriais ou livros de Java 1.2!!

Como eu não estava contente com essas implementações, dei uma fuçada no google e achei uma implementação que é muito simples. Essa implementação tem três linhas de código e gera o mesmo resultado dos monstrengos de 30 linhas.

Segue o código:


import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class TesteCriptografia {

public static void main(String[] args) throws NoSuchAlgorithmException {

String input = "123456";

MessageDigest md = MessageDigest.getInstance("MD5");
BigInteger hash = new BigInteger(1, md.digest(input.getBytes()));
String output = hash.toString(16);

System.out.println(output.toUpperCase());

}

}

Quando é referenciada uma instância de MessageDigest é necessário tratar a exception NoSuchAlgorithmException, porque pode ser lançada caso seja passado um algoritmo que não exista, por exemplo MDiii5. Mas pra que você vai colocar um algoritmo que não exista?!

Eu testei a mesma senha nesta e em mais 2 implementações diferentes e todas deram o mesmo resultado. Então esta é uma implementação que trabalha da mesma forma trazendo os mesmos resultados, porém de uma implementação muito mais simples.

Até o proximo post!

Introdução ao Eclipse RCP

Conheça a plataforma que está revolucionando a maneira de desenvolver sistemas desktop com Java.

 

Autor: André Castiliano

Fonte: http://www.devmedia.com.br/articles/viewcomp.asp?comp=4352

 

A plataforma RCP do eclipse fornece uma maneira simples, poderosa e flexível de desenvolver sistemas desktop usando a linguagem de programação Java.

SWT

O Eclipse utiliza o toolkit gráfico SWT (Standard Widget Toolkit) no lugar do tradicional Swing. Existe muito debate sobre qual o melhor deles, cada qual com suas vantagens e desvantagens. O SWT difere do Swing basicamente por não tentar emular componentes, ele usa os controles e diálogos do sistema operacional sobre o qual a JVM está sendo executada. Isto faz com que as aplicações escritas com base no SWT se pareçam com aplicações nativas, como as escritas em Visual Basic ou Delphi, por exemplo, enquanto que o swing desenha os próprios widgets, que mantêm a consistência nas várias plataformas onde é executado, mas com pequenas falhas por não utilizar componentes nativos (um exemplo clássico sendo a tela de ‘Abrir arquivo’ que, apesar de parecer “real”, é falsa, não propiciando ao usuário as mesmas características que a tela nativa do sistema operacional).

Sem querer entrar no mérito da questão, a característica do SWT de herdar o visual das aplicações nativas (e mais do que isso, de usar os componentes nativos do sistema) é o foco de sua existência, e de extrema importância em alguns ambientes onde já se criou resistência ao Java como linguagem de programação para desktop.

O efeito “eu não acredito que isto é Java” provocado pelo SWT/Eclipse realmente existe. Você verá.

É importante notar que, apesar do SWT ser um componente chave da plataforma eclipse, trata-se de uma biblioteca independente, que pode ser utilizada isoladamente para construir aplicações Java para desktop, de maneira simples e rápida.

JFace

Além do SWT, o eclipse usa extensivamente a biblioteca JFace, que extende o SWT básico, adicionando-lhe novos diálogos, controles e classes úteis.

O JFace também pode ser utilizado fora da plataforma eclipse, adicionando mais poder às suas aplicações SWT.

A figura 01 abaixo mostra a relação entre os componentes da plataforma RCP.

inteclrcpfig01.jpg

Figura 01: Eclipse Workbench

Obviamente existem vários outros componentes dentro da plataforma RCP, mas o ‘workbench’ (este e outros termos serão esclarecidos posteriormente) do eclipse é construído usando-se as bibliotecas SWT e JFace.

Se desejar maiores informações sobre o uso das bibliotecas SWT e JFace fora da plataforma eclipse, leiam o artigo SWT, JFace e Componentes – Parte 1 aqui mesmo na DevMedia.

Plugins

No eclipse, tudo são plugins. O próprio eclipse (IDE) é constituído de um conjunto de plugins inter-relacionados. Suas aplicações RCP são também conjuntos de plugins. O “peso” da plataforma RCP gira em torno de 12MB (Eclipse 3.2) variando de acordo com os recursos utilizados.

Para um maior entendimento, vamos criar o famoso exemplo “Hello World” usando a plataforma Eclipse. Afinal, o que seria de um artigo introdutório à uma nova técnica de programação sem um exemplo Hello World ?

Primeiro, caso ainda não o tenha feito, baixe o Eclipse SDK, do site oficial do projeto. No momento em que este artigo estava sendo escrito a versão estável mais recente era a 3.2.1.

Faça também o download do NL1 (Language Pack) para ter seu eclipse traduzido para pt-BR.

A instalação do eclipse é extremamente simples, basta descompactá-lo numa pasta qualquer e executar o eclipse.exe. Claro, estamos presumindo que você já tenha o J2SE JDK instalado em seu computador. Se ainda não tiver, faça o download no site oficial do Java. Cuidado para não baixar o pacote da JDK6 que vem com o NetBeans junto. J

Hello World

Agora que você está com o ambiente pronto, vamos criar o nosso plugin de teste.

No Eclipse, vá em Arquivo à Novo à Projeto conforme ilustrado na figura 02 mostrada abaixo:

inteclrcpfig02.jpg

Figura 02: Novo projeto no eclipse

Surgirá a tela “Novo projeto mostrada na figura 03:

inteclrcpfig03.jpg

Figura 03: Assistente de novo projeto

Selecione a opção Projeto de Plug-In e clique sobre o botão Avançar.

Agora o assistente de novo projeto exibe uma tela semelhante à figura 04 mostrada abaixo:

inteclrcpfig04.jpg

Figura 04: Configurações iniciais do projeto

Nome do projeto: br.com.devmedia.HelloWorld

Aceite o restante das configurações padrão apresentadas nesta tela.

Clique novamente sobre o botão Avançar e a tela agora se parecerá com a figura 05:

inteclrcpfig05.jpg

Figura 05: Detalhes da configuração do plugin

Esta tela tem 2 opções realmente importantes:

A primeira, dentro do grupo “Opções de Plug-in” informa se este plugin fará ou não contribuições à UI (User Interface) do Eclipse. Num projeto de porte médio ou grande você provavelmente terá plugins que não são gráficos, fornecendo apenas recursos aos demais plugins. Por exemplo um plugin com as classes que servem de interface para a camada de persistência.

A segunda opção está dentro do grupo “Aplicativo de Cliente Rich” e permite a você informar se este plugin é a base de um programa RCP. Por padrão vem marcado como Não, mas para o nosso exemplo será necessário alterar esta configuração para Sim, conforme mostrado na figura 05.

Após preencher as opções desta tela, clique novamente sobre o botão “Avançar” e a tela se parecerá com a figura 06:

inteclrcpfig06.jpg

Figura 06: Modelos de aplicativos RCP para escolher

Uma grata surpresa! O assistente de novo projeto do eclipse nos apresenta uma tela com 4 modelos de aplicativos Rich Client para escolher. Estes modelos servem como base para a criação do seu sistema, evitando que muita coisa precise ser escrita “no braço”.

Utilizando um destes modelos, o próprio Eclipse se encarrega de gerar um esqueleto do projeto com todas as classes necessárias para inicializar corretamente o seu aplicativo.

Para o nosso programa de testes, iremos utilizar o modelo que tem o sugestivo nome de “Hello RCP”. Selecione-o na listagem mostrada, conforme indicado pela figura 06.

Você pode agora clicar sobre o botão “Concluir” e deixar que o Eclipse faça a geração do código necessário ou clicar em “Avançar” e preencher mais algumas informações sobre o projeto, como mostrado na figura 07 abaixo:

inteclrcpfig07.jpg

Figura 07: Ultimas informações sobre o novo plugin

Ao clicar em “Concluir” o Eclipse irá gerar todos os arquivos necessários ao seu projeto. Para executar o seu primeiro programa RCP, clique sobre o link “Ativar um Aplicativo Eclipse” na aba que estará aberta após a confirmação no assistente de novo projeto, conforme ilustrado pela figura 08:

inteclrcpfig08.jpg

Figura 08: Editor de configurações do plugin

Executando o nosso plugin Hello World, obtemos:

inteclrcpfig09.jpg

Figura 09: Primeira aplicação RCP

Agora que você já conhece a plataforma Eclipse e o assistente para criação de novos plugins, sugiro que explore os outros modelos apresentados. Estude as classes geradas pelo assistente e leia a documentação disponível no site oficial do projeto eclipse.

Nos próximos artigos, irei aprofundar mais nos meandros da plataforma Eclipse, mostrando dicas e boas práticas ao trabalhar com a plataforma. Iniciaremos a construção de um pequeno sistema de vendas, que nos permitirá abranger áreas bem distintas, que vão desde a construção de telas internas usando SWT/JFace, os detalhes da camada de persistência até os relatórios finais em jasper reports.Até o próximo artigo.

Primeiro passo para SCJP 5.0 – 310-055

Autor: Angelo Vicente Filho (angelomicrolins@gmail.com)

 

Para fazer uma certificação não é necessário ser um excelente programador Java, mas sim, um conhecedor das peculiaridades da linguagem, por conseqüência, aprendemos a trabalhar nossos programas muito mais profissionalmente.

 

Mas como começamos a estudar essa linguagem? Primeiramente, sabemos que tipo de linguagem é Java? Interpretada ou compilada? Ou ambas? Bem, para que possamos entender vamos ver o que faz a JVM (Java Virtual Machine). Essa máquina pega um arquivo e interpreta-o, mas não pode ser totalmente interpretada, pois se isso fosse verdade ela leria automaticamente os arquivos .java, então o compilador javac compila os arquivos com final .java e a JVM os interpreta o que torna a linguagem Java interpretada e pós-compilada.

 

O que é um programa Java?

Um programa Java nada mais é do que uma coleção de objetos conversando com outros objetos por invocação por métodos. Esses objetos são tipos e esses tipos são definidos por classes e interfaces. Então podemos dizer que os programas Java utilizam coleções de objetos de vários tipos diferentes.

 

»                Classe: É um tipo definido pelo usuário que possui especificações (características e comportamentos) que o identifiquem. De uma maneira mais genérica podemos dizer que uma classe nada mais é do que um molde que será usado para construir objetos que representam elementos de vida real.

Classe = Características + Comportamentos;

 

»                Objetos: Digamos que temos um molde chamado Produtos e se eu perguntasse o que é um produto para você o que você iria responder? Para cada pessoa, um produto pode se diferenciar de uma pessoa para outra, isto é, o que pra mim um produto é um carro, para outro um produto pode ser um livro, basta ver o que foi que nós pensamos na hora de que foi feita a pergunta. Imaginamos que o produto fosse um livro. Core Java com preço de R$ 150,00. Quando nos lembramos de um produto isso ficou meio abstrato em nossa cabeça, mas quando falamos que o produto é um livro, veio a nossa cabeça vários livros e isso faz com que a abstração seja mais restrita e quando eu falei que o livro era o Core Java veio o livro em nossas mentes. O que eu quero dizer com isso? Bem, quando falamos em objetos falamos que o molde tomou forma, o objeto nada mais é do que a forma de como instanciamos as classes, e ele tem vida independente entre si apesar de compartilharem o mesmo molde. Exemplo é o ovo de chocolate da páscoa, tem um molde (Classe) e é feito vários ovos (objetos) e cada ovo é diferente do outro o que faz dizer que eles têm vida própria. Um objeto é criado quando utilizamos o operador new.

 

»                Métodos: Através dos métodos definimos as operações que podem ser executadas com ou sobre um objeto. Popularmente diz-se que os métodos definem o comportamento da classe.

 

Fundamentos da Linguagem

Lembrando que aqui usarei todos os padrões do JavaBeans, porém temos que saber que o que manda para a prova da Sun é o que o compilador executa.

 

Lembre-se também que colocarei aqui o que é necessário para que você possa ler e separar para criar a sua lista de estudos, então o que estiver dentro de caixas são muito importante e se você colocar separado em um arquivo e depois ler vai fazer um resumo de tudo aquilo que está aprendendo. E para começar veremos a parte de identificadores.

 

Identificadores Legais

Tecnicamente os identificadores legais são compostos somente por caracteres Unicode, números, símbolos de moeda ($), e conexão de caracter, conhecido como underline ou underscores. Aqui coloquei o que você precisa saber.

 

Identificadores somente começam com letras, símbolo de moeda e underscore ( _ ). Identificadores não podem começar com números!

Depois do primeiro caracter poderá haver a combinação de letras, números e símbolos.

Você não pode usar palavras reservadas Java como identificador. A lista de palavras reservadas aparecerá logo abaixo.

Identificadores Java são case-sensitive; logo foo e FOO são dois identificadores diferentes. {Não existe identificador com letras maiúsculas}

 

Exemplo de identificadores legais:

int _a;

int $c;

int __________2_w;

int _$;

int este_e_um_identificador_valido;

 

Exemplo de identificadores ilegais:

int :b;

int –d;

int #e;

int .fff;

int 7up;

 

avfpripscjpfig01.jpg 

Esta é a lista de palavra reservada

 

Sei que este artigo está meio teórico, mas isso somente acontecerá nos dois primeiros artigos, quando trabalharemos práticas de programação. Até a próxima.

Criando um site dinâmico – Parte I

Autor:

Marcelo Castellani (castellani@itautec.com) é analista de sistemas sênior na Itautec S/A e atua na área de desenvolvimento desde 1996, passando por linguagens como Visual Basic, C, C++ e Java. Mantém o blog hype quino (www.hypequino.com) aonde fala de novas tecnologias em matérias curtas.

 

Fonte: http://www.devmedia.com.br/articles/viewcomp.asp?comp=7241

 

O que é um site dinâmico ?

Temos dois tipos de projeto Web disponíveis no Eclipse, o dynamic web project e o static web project. A diferença entre ambos é que o dynamic, como o próprio nome diz, possibilita o uso de recursos do J2EE que tornam o site dinâmico, como servlets, arquivos JSP, filtros e metadados associados, além de recursos disponíveis para sites do tipo static. Este tipo de projeto web suporta apenas tecnologias padrão, como imagens, páginas HTML, CSS e afins.

 

Projetos dynamic estão sempre encapsulados em um projeto do tipo Enterprise Application Project (EAR), e  o assistente de criação de um projeto dynamic sempre cria um projeto EAR caso este não exista. O assistente também atualiza o descritor de distribuição do projeto EAR para definir o novo Web Project como um elemento do módulo.

 

Criando um novo projeto com o assistente

Com o Eclipse aberto vá em File – New – Project. A janela abaixo será mostrada:


mfccsdp1fig01.jpg

Na lista selecione a opção Web – Dynamic Web Project e clique no botão Next.


mfccsdp1fig02.jpg

A janela abaixo será mostrada.


mfccsdp1fig03.jpg

Você deverá informar as definições do projeto, a saber:

l  Project name: é o nome do projeto, no nosso caso será Projeto01;

l  Project Contents: é o diretório de destino dos arquivos do projeto. Mantendo a opção Use Default marcada faz com que o Eclipse salve as informações no workspace atual, desmarcando permite escolher outro destino. No nosso caso manteremos a opção Use Default marcada;

l  Target Runtime: é o servidor de aplicação a ser usado para rodar o projeto. Em nosso caso vamos adicionar um novo servidor, clicando no botão New. A janela abaixo será mostrada:

 

 mfccsdp1fig04.jpg

 

l  Selecione o Apache Tomcat v5.5 e clique em Next. Você deverá informar o diretório raiz de instalação do Tomcat, um nome para o servidor e qual a JRE a usar, como na figura abaixo. Feito isso clique em Finish;

 

mfccsdp1fig05.jpg

 

l  EAR Membership: caso o projeto vá fazer parte de um projeto do tipo EAR já existente marque a opção add project to an EAR e selecione o projeto na caixa de combinação abaixo. No nosso caso, como falamos ao Eclipse que nosso projeto vai rodar direto no servidor de aplicações, a opção é desabilitada e um novo projeto EAR será criado automaticamente, com o nome de nosso projeto principal, como pode ser visto na imagem abaixo:

 

mfccsdp1fig06.jpg

 

Com tudo definido clique em Finish para iniciar a criação de nosso projeto. Caso seja aberta uma janela com um contrato de licença da Sun apenas clique em Accept. É interessante prestar atenção no topo da página pois nela serão mostradas dicas em caso de problemas. Abaixo você pode ver uma dica, que diz que o nome do projeto não pode estar em branco.

 

mfccsdp1fig07.jpg

 

Entendendo a estrutura de diretórios criada

O Eclipse irá criar automaticamente a estrutura de diretórios e arquivos de nosso projeto, como abaixo:

 

mfccsdp1fig08.jpg

 

Esta estrutura é definida pela J2EE, no documento Sun Microsystems Java™ Servlet 2.5 Specification, aonde toda a estrutura de uma aplicação web é detalhada, definindo a localização de páginas web, arquivos class, caminhos, descritores de distribuição e outros mais.

 

A pasta principal (no nosso caso Projeto01) contém todos os artefatos relacionados a nossa aplicação web e dentro dela encontramos diversos elementos, descritos a seguir. É importante ressaltar que esta estrutura de pastas mapeia a estrutura de um arquivo de aplicação web (Web application archive – WAR), definido também pela Sun Microsystems.

 

A edição deste arquivo, no Eclipse, é feito através de uma interface gráfica, bastando clicar sobre Deployment Descriptor: Projeto01, no project explorer.

mfccsdp1fig09.jpg

 

l  Java Resource (src): Contém o código fonte Java de servlets, classes e beans. O conteúdo deste diretório não é adicionado automaticamente ao WAR que for gerado, apenas se for implicitamente adicionado quando o WAR for criado. Os arquivos deste diretório são compilados diretamente no diretório WEB-INF/classes, em WebContent;

l  WebContent: Diretório principal, aonde encontramos todos os recursos de web, como páginas, arquivos gráficos e afins. Também ficam aqui os arquivos JSP. Dentro dela encontramos as pastas META-INF e WEB-INF.

 

Em META-INF encontramos o arquivo MANIFEST.MF, que é usado para mapear caminhos de classes que sejam dependências de nosso projeto.

 

Em WEB-INF temos o diretório lib, aonde devem ser colocadas bibliotecas que sejam necessárias a aplicação.