26 de setembro de 2006

Primeiro teste com JEE5

Bom galera, depois de muuuuuito tempo sem postar nada, resolvi fazer um teste neste fim de semana e como ficou melhor do que o esperado achei melhor compartilhar com vocês.

Resolvi fazer um pequeno teste (tambem chamado testículo) com JEE5 e ver como ele se comporta na prática, já tinha ouvido e lido sobre o aumento da produtividade, que é mais facil, etc... Até agora eu só tinha visto exemplos de JPA, EJB 3.0, JSF 1.2, etc... mas não tinha visto um com tudo junto, então resolvi fazer o meu. É uma aplicação simples, apenas uma agenda de telefone/e-mail funcionando tudo numa tela, inclusão, alteração, exclusão e consulta, um CRUDizinho sem vergonha.

Como IDE resolvi usar o NetBeans 5.5 beta 2, que tem suporte completo e ja vem com o Sun Java System Application Server que implementa a JEE5, e se eu não estiver enganado é a base do GlassFish. Cheguei até ver na net como fazer para o usar o GlassFish, mas acabei perdendo o link e não achei mais, e como eu tambem não tava com muita esperança de que tudo fosse funcionar, nem liguei, mas depois vou correr atraz ;-) (bem como vou ver se tem como fazer isso tudo no Eclipse tambem).

Bom então vamos lá, pra começar temos que baixar o NetBeans 5.5 beta 2 e instalá-lo. Depois de instalado, basta executá-lo (dããã) :)

A primeira coisa que vamos fazer é criar a base de dados e a tabela da nossa agenda. O NetBeans 5.5 beta 2 vem com Java DB, que é baseado no Derby que é baseado no Cloudscape (ufa), acredito que você possa usar quaquer banco de dados, eu usei este porque ja vinha com ele e como o foco era fazer o JEE5 funcionar ficou ele mesmo.

Para criar a base de dados, vá no menu Tools>Java DB Database>Create Java DB Database, na janela de diálogo basta preencher todos os campos com "agenda": database name, user e password. Assim a vida fica mais facil :P

Na "abinha" de runtime, em databases nossa base irá aparecer (se você for abrindo os nodes, claro). Clique com o botão direito sobre ela e selecione connect para abrir a conexão.

Agora vamos criar a nossa tabelinha, com a conexão aberta, clique com o botão direito novamente sobre a base e selecione Execute command, isto irá abrir uma janela para executarmos comandos SQL, entre com a instrução abaixo para criarmos nossa tabelinha:


create table tb_agenda (
id integer generated always as identity constraint id_pk primary key,
nome varchar(50) not null,
telefone varchar(30),
email varchar(30),
dtnascimento date
);



Agora ja temos que temos nossa base com nossa tabelinha, vamos criar o nosso projeto. Então vamos lá, menu File>New Project selecione Enterprise e Enterprise Application, para criarmos nosso EAR. Na janela basta entrar com o nome do Projeto Agenda, deve estar marcada como default a opção para JEE5, mas não custa nada confirmar, o restante deixe como default. Devem ter sido criadas 3 entradas na lista de projetos do NetBeans, Agenda (ear), Agenda-ejb e Agenda-war.

Precisamos agorar criar a configuração da persistencia do EJB 3.0, o persistence.xml. Para isso o NetBeans tem um wizard que quebra um galho, clique com o botão direito sobre o Agenda-ejb selecione New>Persistence Unit. Deixe as opções default (ate mesmo o nome), verifique se está apontando para o datasource correto, no meu teste eu deixei como Persistence Provider o Toplink, mas acredito que possa ser usado o Hibernate ou o Kodo, em todo caso isto pode ser alterado mais tarde sem maiores dificuldades, basta editar o persistence.xml.



Depois de terminarmos será criado o seguinte conteúdo para o arquivo:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="Agenda-ejbPU" transaction-type="JTA">
<jta-data-source>jdbc/agenda</jta-data-source>
<properties></properties>
</persistence-unit>
</persistence>


Chegou a hora de criarmos nosso objeto para representar os dados da agenda, que deve se chamar Agenda (oh!). Vamos colocar nossa classe no pacote agenda, do projeto Agenda-ejb, segue abaixo o código:


package agenda;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
@Entity
@Table(name="tb_agenda")
public class Agenda implements java.io.Serializable {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="id")
private int id;

@Column(name="nome",length=50)
private String nome;

@Column(name="telefone",length=40)
private String telefone;

@Column(name="email",length=30)
private String email;

@Column(name="dtnascimento")
@Temporal(TemporalType.DATE)
private Date dtnascimento;

public int getId(){ return id; }

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

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

public String getEmail() { return email; }

public void setEmail(String email) { this.email = email;}

public Date getDtnascimento() { return dtnascimento; }

public void setDtnascimento(Date dtnascimento){
this.dtnascimento = dtnascimento;
}
}

Não vou perder tempo explicando as annotations, porque isto já esta ficando grande e porque já tem um monte de site explicando isto :P (sem contar que na javamagazine deste mes tem uma materia sobre JPA).

Agora temos que criar nosso EJB de negócio, um stateless simples que sera acessado pela aplicação web e persistira o nosso Entity agenda usando JPA. Novamente clique com o botão direito sobre o Agenda-ejb selecione New>Session Bean, na janela de diálogo preencha o nome do EJB com Agenda, o pacote tambem pode ser agenda. Serão criados dois arquivos, a classe AgendaBean que é nosso ejb e a interface local AgendaLocal.

Agora vem o exercicio preferido: ctrl+c ctrl+v :) primeiro para o AgendaBean:


package agenda;
import java.util.List;
import javax.annotation.Resource;
import javax.ejb.Stateless;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.transaction.HeuristicMixedException;
import javax.transaction.HeuristicRollbackException;
import javax.transaction.NotSupportedException;
import javax.transaction.RollbackException;
import javax.transaction.SystemException;
import javax.transaction.UserTransaction;

@Stateless
@TransactionManagement(value=TransactionManagementType.CONTAINER)
public class AgendaBean implements agenda.AgendaLocal {

@PersistenceContext
private EntityManager manager;

public void salvar(Agenda agenda) {
if (agenda.getId()>0)
manager.merge(agenda);
else
manager.persist(agenda);
}
public void excluir(Agenda agenda) {
Agenda ag =manager.merge(agenda);
manager.remove(ag);
}
public List consultar() {
Query q =manager.createQuery("select a from Agenda a");
return q.getResultList();
}
}


Agora é a vez da interface:


package agenda;
import java.util.List;
import javax.ejb.Local;

@Local
public interface AgendaLocal {
public void salvar(Agenda agenda);
public void excluir(Agenda agenda);
public List consultar();
}

Nossa camada de negócios está pronta agora temos que fazer a nossa camada web (e dalhe MVC).

A primeira coisa a ser feita é configurar a servlet do JSF no web.xml, para isso vá la no projeto Agenda-war e abra o web.xml e faça com que fique assim (e tome ctrl+c ctrl+v)




<?xml version="1.0" encoding="UTF-8"?>
<web-app 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"
version="2.5">
<session-config>
<session-timeout>30</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<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>
</web-app>

Agora vamos criar o arquivo faces-config.xml, na pasta WEB-INF clique com o botão direito selecione New>XML Document nome do arquivo faces-config e deixe as opções default, o resto você ja sabe (mais ctrl+c ctr+v, afinal se chegou ate aqui você já deve estar craque nisso).


<faces-config 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"
version="1.2">
<managed-bean>
<managed-bean-name>agendaMB</managed-bean-name>
<managed-bean-class>agenda.AgendaMB</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
</faces-config>


E já que declaramos o agenda.AgendaMB, vamos então criá-lo, seguindo o mesmo ritual, botão direito, New>Java Class ........ ctrl+v.


package agenda;
import java.util.Date;
import javax.ejb.EJB;
import javax.faces.context.FacesContext;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;

public class AgendaMB {
private Agenda agenda;
private DataModel lista;

@EJB
private AgendaLocal agendaBean;

public void salvar(){
agendaBean.salvar(agenda);
this.agenda = null;
this.lista = null;
}
public void excluir(){
agendaBean.excluir(agenda);
this.agenda = null;
this.lista = null;
}
public DataModel getLista(){
if (lista==null) {
lista = new ListDataModel(agendaService.consultar());
}
return lista;
}
public void selecionar(){
agenda = (Agenda) lista.getRowData();
}
public Agenda getAgenda(){
if (agenda ==null)
agenda =new Agenda();
return agenda;
}
}


Agora vamos a parte chata, criar a pagina jsp para nossa agenda, afinal vamos ter que fazer mais ctrl+c ctrl+v. Mais uma vez botão direito..... O nome da página será agenda (dã!).


<%@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>
<title>Agenda</title>
</head>
<body>
<h1>Agenda</h1>
<h:form>
<h:panelGrid columns="2">
<h:outputLabel id="labelID" value="ID" />
<h:panelGroup>
<h:inputText id="id" value="#{agendaMB.agenda.id}"
disabled="true" label="labelID">
<f:convertNumber integerOnly="true"/>
</h:inputText>
<h:message for="id"
errorStyle="color:red"/>
</h:panelGroup>
<h:outputLabel id="labelNome" value="Nome"/>
<h:panelGroup>
<h:inputText id="nome" value="#{agendaMB.agenda.nome}"
label="labelNome" size="40" maxlength="50"
required="true"/>
<h:message for="nome"
errorStyle="color:red"/>
</h:panelGroup>
<h:outputLabel id="labelTelefone" value="Telefone"/>
<h:panelGroup>
<h:inputText id="telefone"
value="#{agendaMB.agenda.telefone}"
label="labelTelefone" size="20"
maxlength="30"/>
<h:message for="telefone"
errorStyle="color:red"/>
</h:panelGroup>
<h:outputLabel id="labelEmail" value="E-Mail"/>
<h:panelGroup>
<h:inputText id="email"
value="#{agendaMB.agenda.email}"
label="labelEmail" size="30" maxlength="30"/>
<h:message for="email"
errorStyle="color:red"/>
</h:panelGroup>
<h:outputLabel id="labelNascimento"
value="Data de Nascimento"/>
<h:panelGroup>
<h:inputText id="dtnascimento"
value="#{agendaMB.agenda.dtnascimento}"
label="labelNascimento" size="12" maxlength="10">
<f:convertDateTime pattern="dd/MM/yyyy" />
</h:inputText>
<h:message for="dtnascimento"
errorStyle="color:red"/>
</h:panelGroup>
<f:facet name="footer">
<h:panelGroup>
<h:commandButton value="Salvar"
action="#{agendaMB.salvar}" />
<h:commandButton value="Excluir"
action="#{agendaMB.excluir}"
rendered="#{agendaMB.agenda.id>0}" />
</h:panelGroup>
</f:facet>
</h:panelGrid>
</h:form>
<hr/>
<h:form>
<h:dataTable value="#{agendaMB.lista}" var="linha">
<h:column>
<f:facet name="header">
<h:outputText value="ID"/>
</f:facet>
<h:commandLink action="#{agendaMB.selecionar}" >
<h:outputText value="#{linha.id}" />
</h:commandLink>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Nome"/>
</f:facet>
<h:outputText value="#{linha.nome}" />
</h:column>
</h:dataTable>
</h:form>
</body>
</f:view>
</html>


E por último vamos alterar a pagina index.jsp que é criada por default para que ela redirecione para nossa página, é só apagar tudo que tem la e incluir este bloco imenso de código (o maior ate agora):

<jsp:forward page="agenda.jsf" />

(pelo menos a fonte é a maior :)

Agora é só executar a aplicação e começar a cadastrar os contatos. Num próximo post vou comentar alguns passos (afinal isto aqui ja ta grande pacas).



E por favor comentem pra eu saber que não foi só a minha esposa que viu :P