144
UNIVILLE - Universidade da Regi˜ ao de Joinville Departamento de Inform´ atica DSI - Desenvolvimento de Sistemas de Informa¸c˜ ao Desenvolvimento de Sistemas Cliente - Servidor utilizando JEE, Adobe Flex 4, Swing ou JSF v1.0 Prof. Walter Silvestre Coan 28 de mar¸co de 2016 Este material foi elaborado em L A T E X

Desenvolvimento de Sistemas Cliente - Servidor utilizando

  • Upload
    others

  • View
    2

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Desenvolvimento de Sistemas Cliente - Servidor utilizando

UNIVILLE - Universidade da Regiao de JoinvilleDepartamento de Informatica

DSI - Desenvolvimento de Sistemas de Informacao

Desenvolvimento de Sistemas Cliente -

Servidor utilizando JEE, Adobe Flex 4,

Swing ou JSFv1.0

Prof. Walter Silvestre Coan

28 de marco de 2016Este material foi elaborado em LATEX

Page 2: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Sumario

1 Introducao 31.1 Arquiteturas de Sistemas de Informacao . . . . . . . . . . . . . . . . . . . 3

1.1.1 Arquitetura baseada em Database Centric . . . . . . . . . . . . . . 31.1.2 Arquitetura baseada em Aplicacao WEB . . . . . . . . . . . . . . . 41.1.3 Arquitetura baseada em Servidor de Aplicacao . . . . . . . . . . . . 5

2 Configuracao do ambiente de desenvolvimento 82.1 Instalacao e configuracao do servidor Glassfish . . . . . . . . . . . . . . . . 82.2 Instalacao e configuracao da IDE de desenvolvimento - Adobe FLEX . . . 16

3 Desenvolvimento 253.1 Construcao da camada de negocio . . . . . . . . . . . . . . . . . . . . . . . 253.2 Implementando o projeto EJB . . . . . . . . . . . . . . . . . . . . . . . . . 293.3 Mapeamento Objeto Relacional - JPA (Java Persistence API) . . . . . . . 443.4 Implementando a aplicacao cliente em JSF - Java Server Faces . . . . . . . 48

3.4.1 Iniciando o desenvolvimento de um cadastro simples com JSF . . . 583.4.2 Implementando formularios no JavaServer Pages . . . . . . . . . . . 653.4.3 Implementando associacao entre classes . . . . . . . . . . . . . . . . 723.4.4 Implementando um cadastro pai-filho . . . . . . . . . . . . . . . . . 83

3.5 Implementando a aplicacao cliente em Adobe Flex 4 . . . . . . . . . . . . . 1063.5.1 Configuracao do BlazeDS para acesso aos EJBs . . . . . . . . . . . 1133.5.2 Desenvolvimento da aplicacao cliente em Flex 4 . . . . . . . . . . . 1163.5.3 Primeiro deploy da aplicacao . . . . . . . . . . . . . . . . . . . . . . 125

3.6 Implementando a aplicacao cliente em Swing . . . . . . . . . . . . . . . . . 1303.6.1 Configuracao do projeto Swing . . . . . . . . . . . . . . . . . . . . 1303.6.2 Iniciando a codificacao . . . . . . . . . . . . . . . . . . . . . . . . . 136

2

Page 3: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Capıtulo 1

Introducao

1.1 Arquiteturas de Sistemas de Informacao

Todo sistema de informacao, possui uma arquitetura basica que lhe prove suportepara seu funcionamento. Pode-se entender por arquitetura de software como a definicaodos principais componentes que serao agrupados para que o sistema possa ser construıdo,testado e utilizado. O trabalho do arquiteto de software exige a definicao detalhada detodos esses componentes com o objetivo de garantir o correto funcionamento, alem deconceitos como interoperabilidade (possibilidade do sistema se comunicar com outros sis-temas desenvolvidos em diferentes tecnologias), escalabilidade (possibilidade de expandira capacidade de suportar um maior numero de funcionalidades e de usuarios conectadosao sistema, com pouca ou nenhuma alteracao no codigo fonte) e disponibilidade.

1.1.1 Arquitetura baseada em Database Centric

Diversas arquiteturas de sistemas foram desenvolvidas ao longo da evolucao dos sis-temas de informacao. Muitas dessas arquiteturas foram motivadas pelo desenvolvimentode novas linguagens de programacao e sistemas gerenciadores de bancos de dados. Aprincipal arquitetura para sistemas de informacao, ate hoje utilizada, e a conhecida comocentrada em bancos de dados (Database Centric). Conforme a Figura 1.1, a principalcaracterıstica desta arquitetura esta no fato de que o servidor de banco de dados, onde eexecutado o SGBD 1, e responsavel por centralizar todas informacoes do sistema. Alemdisso, o SGBD resolve outras problemas comuns de qualquer tipo de sistema de informacaocomo:

• Multiplas conexoes: como o sistema de informacao precisa ser acessado por diversosusuarios, muitas vezes de forma simultanea, o SGBD permite que varias estacoes detrabalho utilizando uma infraestrutura de rede, realizem conexoes e troquem dadoscom o servidor sem a necessidade de um controle por parte do aplicativo cliente;

• Concorrencia: caso dois ou mais usuarios executem uma acao no sistema de in-formacao de forma concorrente, em qual ordem essas acoes serao persistidas nobanco de dados? O SGBD possui servicos e algoritmos que garantem a Atomici-dade, Consistencia, Isolamento e Durabilidade dos dados;

1SGBD - Sistema Gerenciador de Bancos de Dados

3

Page 4: Desenvolvimento de Sistemas Cliente - Servidor utilizando

• Troca de informacoes: com a existencia de um unico ponto centralizador, que e oSGBD, os demais usuarios do sistema trocam informacoes utilizando o processo decriacao de registros nas tabelas do banco de dados. Desta maneira simples, e possıvelque o estado do sistema de informacao para um usuario possa ser compartilhadocom outros usuarios conectados ao mesmo sistema.

Algumas desvantagens sao observadas neste tipo de arquitetura como: forte acoplamentoda aplicacao a tecnologia de banco de dados, impossibilitando muitas vezes a troca doSGBD devido a necessidade de adaptacao ou ate reescrita do codigo fonte da aplicacaopara isso; falta de controle sobre o melhor momento para persistencia dos dados - como oestado da aplicacao e mantido pela persistencia dos dados no SGBD, todas as alteracoesprecisam ser persistidas imediatamente para que os demais usuarios tenham acesso a elas,porem esse processo pode degradar a performance em aplicacoes que precisam suportarum volume muito grande de usuarios concorrentes; seguranca - caso haja necessidade deum acesso ao sistema de forma remota, fora de rede local, o banco de dados necessita serexpostos a conexoes via internet ou outras redes, o que se torna um fator de risco para aseguranca dos dados contidos na aplicacao.

Figura 1.1: Arquitetura Database Centric

1.1.2 Arquitetura baseada em Aplicacao WEB

O segundo tipo de arquitetura de sistemas de informacao existente sao as baseadas emaplicacoes WEB. Conforme a Figura 1.2, neste tipo de aplicacao as estacoes de trabalhoutilizam uma conexao de rede que pode ser local como a internet para acessar a umservidor WEB. Este servidor possui um servico que responde, normalmente, atraves daporta 80, requisicoes do protocolo HTTP 2 devolvendo as estacoes de trabalho paginascom conteudo de hipertexto e recebendo dessas estacoes requisicoes de novas paginas.As paginas contidas no servidor WEB, podem ser estaticas, ou dinamicas que consistena juncao de codigo em linguagem de programacao a TAGs de definicao do layout. Essecodigo inserido nas paginas e que prove a dinamicidade, pois os dados apresentados podemser originados de uma consulta a um banco de dados.

2HTTP - Hyper Text Transfer Protocol

4

Page 5: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 1.2: Arquitetura Aplicacao WEB

As principais vantagens desta arquitetura sao:

• Portabilidade: como o protocolo HTTP e portavel para diferentes tipos de sistemasoperacionais, ele permite que qualquer tipo de equipamento tenha acesso a aplicacao;

• Seguranca: como o servidor de banco de dados e acessado apenas pela aplicacao exe-cutada no servidor WEB, e possıvel um melhor controle do acesso aos dados, apesarde que a exposicao da aplicacao ao ambiente da Internet a torna mais propensa aataques de invasao.

Ja a principal desvantagem deste tipo de aplicacao e a escalabilidade: em sua definicao,as principais tecnologias de desenvolvimento WEB, nao possuem requisitos definidos quegarantam a escalabilidade da aplicacao, deixando essa caracterıstica para ser resolvidapelos servicos que sao instalados nos servidores.

1.1.3 Arquitetura baseada em Servidor de Aplicacao

Dentro deste tipo de arquitetura podemos destacar as tecnologias: CORBA, JEE- Java Enterprise Edition e WCF - Windows Communication Foundation. Neste tipode arquitetura, conforme a Figura 1.3, um conjunto de servicos compoe o servidor deaplicacao que e o ambiente onde o sistema de informacao e executado. Este servidorde aplicacao pode prover servicos como: servico WEB, servico de objetos distribuıdos,servico de controle de transacao, servico de entrega de mensagens assıncronas, servicoe-mail dentre outros. A principal vantagem desta arquitetura e que caso haja necessidadede escalabilidade da aplicacao, novos servidores fısicos ou virtuais podem ser acopladosna forma de grupos, sem a necessidade de modificar o codigo fonte da aplicacao. Alemdisso, como o sistema de informacao e executado no servidor de aplicacao, as estacoes detrabalho podem acessa-la atraves de aplicacoes clientes leves, destinando o processamentopesado para o servidor de aplicacao.

5

Page 6: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 1.3: Arquitetura Servidor de Aplicacao

A plataforma JEE - Java Enterprise Edition, conforme a Figura 1.4, e normalmentecomposta por 4 camadas: a primeira camada de apresentacao ou tambem conhecida porcamada cliente, e a instalada nas estacoes de trabalho ou acessada atraves de um navega-dor WEB, podendo tambem ser composta por outro tipo de tecnologia como um clienteAndroid; ja dentro do servidor de aplicacao temos a primeira camada de apresentacaoque pode ser composta por tecnologias como JSP, Servlets, Web Services que permitem ainteroperabilidade com diferentes tipos de aplicacoes clientes; a segunda camada chamadade Business Logic, e composta por objetos conhecidos como EJB - Enterprise Java Beans,que sao objetos para construcao da logica de negocio da aplicacao e que serao executadosno servidor de aplicacao provendo servicos a camada de apresentacao; e por fim a quartacamada que pode ser composta por SGBDs ou outros tipos de sistemas que funcionemcomo fonte de dados para o sistema de informacao.

Figura 1.4: Arquitetura Plataforma JEE - Java Enterprise Edition

Para o desenvolvimento do projeto de DSI foi selecionada a seguinte arquitetura ilus-trada pela Figura 1.5. Como servidor de aplicacao sera utilizado a implementacao dereferencia da Oracle chamada Glassfish. Este servidor de aplicacao e uma implementacao

6

Page 7: Desenvolvimento de Sistemas Cliente - Servidor utilizando

completa da plataforma JEE, sendo que dois servicos da plataforma serao utilizados oContainer EJB para abrigar os objetos EJB com a logica de negocio da aplicacao, e osobjetos JPA - Java Persistence API para a persistencia dos dados do sistema atraves datecnica de Mapeamento Objeto Relacional, alem do WEB Container onde sera configu-rado o BlazeDS que e um conjunto de APIs para a comunicacao entre a plataforma JEE ea tecnologia Adobe Flex 4. Para a camada cliente, serao utilizadas duas tecnologias: paraaplicacoes desktop a plataforma de desenvolvimento Java Standard Edition com a inter-face grafica em Swing e para aplicacoes WEB a plataforma de desenvolvimento AdobeFlex 4. No ambiente desktop a comunicacao com o servidor se dara atraves do protocoloJava RMI - Remote Method Invocation, que permite a invocacao de metodos dos objetosEJB atraves de uma rede que utilize o protocolo TCP/IP, ja para o ambiente WEB, acomunicacao entre a aplicacao cliente em Adobe Flex 4 e o BlazeDS no servidor JEEocorre atraves do protocolo AMF - Action Message Format.

Figura 1.5: Arquitetura Arquitetura escolhida para o projeto de DSI

7

Page 8: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Capıtulo 2

Configuracao do ambiente dedesenvolvimento

2.1 Instalacao e configuracao do servidor Glassfish

Para instalacao do servidor Glassfish, e necessario realiza o download do arquivo zipcontendo o servidor que pode ser realizado pelo endereco: http://glassfish.java.net/. Con-forme ilustra a Figura 2.1 o arquivo contendo o servidor deve ser descompactado em umdiretorio do computador, sugerindo-se nao realizar esse processo dentro de diretorios pro-tegidos dos sistemas operacionais como Program Files no Windows.

Figura 2.1: Estrutura de diretorios do Glassfish

Apos descompactar o servidor, e necessario instalar o driver JDBC no servidor Glass-fish para que a aplicacao tenha acesso ao banco de dados, conforme ilustra a Figura 2.2, osarquivos dos drivers devem ser copiados para o diretorio: glassfish\domains\domain1\lib\ext.

8

Page 9: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 2.2: Instalacao dos drivers JDBC no servidor Glassfish

Com a conclusao da instalacao o servidor Glassfish, pode-se inicializa-lo conforme aFigura 2.3, acessando o terminal do Windows (CMD) e navegando ate o diretorio BINonde o glassfish foi instalado basta executar os seguintes comandos:

• asadmin - comando para inicializar o console de administracao do Glassfish

• start-domain - comando para inicializar o servidor Glassfish

Figura 2.3: Processo de inicializacao do servidor Glassfish

Configuracao para acesso ao banco de dados Microsoft SQLServer

Ao receber a mensagem de que o servidor Glassfish foi inicializado com sucesso, enecessario acessar atraves de um navegador a interface de configuracao do servidor, paraisso acesse o endereco: http://localhost:4848. Como ilustrado na Figura 2.4, e necessarioconfigurar servidor para que tenha acesso ao banco de dados, visto que todo o controle detransacao da aplicacao e realizado pelo servidor de aplicacao. IMPORTANTE: toda aconfiguracao para a criacao do banco de dados e permissao de acesso ja deveraestar configurada no Microsoft SQLServer.

Ao acessa a interface web de configuracao do Glassfish, clique nas opcoes do menu:RESOURCES ->JDBC ->JDBC CONNECTION POOLS e na tela que sera apresentadado lado direito, selecione a opcao NEW.

9

Page 10: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 2.4: Configuracao para acesso ao banco de dados Microsoft SQLServer - Passo 1

O proximo passo e inserir o Pool Name, conforme a Figura 2.5,que e o nome como qual o servidor ira identificar a conexao com o banco de dados. No campo ResourceType selecione a opcao java.sql.Driver que indica que sera utilizado um driver JDBCpara a conexao com o banco de dados. No segundo campo do item Database Dri-ver Vendor, informe o caminho do classpath para o driver JDBC do MSSQL, que e:com.microsoft.sqlserver.jdbc.SQLServerDriver, para entao acionar a opcao NEXT no topoda tela.

Figura 2.5: Configuracao para acesso ao banco de dados Microsoft SQLServer - Passo 2

Na proxima tela, conforme a Figura 2.6, selecione a opcao Ping ENABLE, para que oservidor Glassfish realize o teste da conexao com as configuracoes informadas.

10

Page 11: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 2.6: Configuracao para acesso ao banco de dados Microsoft SQLServer - Passo 3

Ainda na mesma interface, porem nas ultimas propriedades conforme a Figura 2.7,informe a string de conexao com o banco de dados no parametro URL e o usuario e senhaque foi configurado no banco de dados para o acesso. A string de conexao para o MSSQLdeve seguir o seguinte padrao:

jdbc:sqlserver://localhost:1433;databaseName=NOMEDOBANCODEDADOS;user=USUARIO;password=SENHA

Figura 2.7: Configuracao para acesso ao banco de dados Microsoft SQLServer - Passo 3

Para concluir esse processo, selecione a opcao FINISH nesta mesma tela, no fim dapagina.

O proximo passo e disponibilizar a conexao criada com o banco de dados como umrecurso disponıvel na aplicacao que sera desenvolvida. Para isso, como ilustra a Figura

11

Page 12: Desenvolvimento de Sistemas Cliente - Servidor utilizando

2.8, acesse a opcao RESOURCE ->JDBC ->JDBC RESOURCES e entao acione a opcaoNEW.

Figura 2.8: Configuracao para acesso ao banco de dados Microsoft SQLServer - Passo 4

Na proxima interface, conforme a Figura 2.9, informe o JNDI Name e selecione aconexao no Pool Name. O JNDI Name pode seguir o seguinte padrao: jdbc/NOMEDA-CONEXAO. Para concluir, basta clicar na opcao OK no topo da interface.

Figura 2.9: Configuracao para acesso ao banco de dados Microsoft SQLServer - Passo 5

Configuracao para acesso ao banco de dados MySQL

Para realizar o mesmo processo de configuracao, mas utilizando o banco de dadosMySQL, sera necessario realizar os seguintes passos a seguir. Como ilustra a Figura 2.10,sera necessario acessar a interface de administracao do banco de dados MySQL para a

12

Page 13: Desenvolvimento de Sistemas Cliente - Servidor utilizando

criacao de um banco e dados e liberacao do acesso a um usuario, para isso acesse oterminal console do Windows (CMD), e digite o seguinte comando para iniciar o consoleadministrativo do banco:

mysql -u root -pEm seguida, informe a senha do usuario root que foi definida no processo de instalacao

do banco de dados. Para verificar quais bancos ja foram criados, utilize o comando: showdatabases;

Para criar um novo banco, utilize o comando: create database NOMEDOBANCO;Apos a confirmacao de que o banco foi criado e necessario liberar a permissao de

acesso a um usuario que sera utilizado pelo servidor Glassfish, atraves do seguinte co-mando: grant all privileges on NOMEDOBANCO.* to USUARIO@localhost identifiedby ´SENHA´;

Para confirmar as permissoes liberadas execute o comando: flush privileges;

Figura 2.10: Configuracao para acesso ao banco de dados MySQL - Passo 1

Ao acessa a interface web de configuracao do Glassfish, clique nas opcoes do menu:RESOURCES ->JDBC ->JDBC CONNECTION POOLS e na tela que sera apresentadado lado direito, selecione a opcao NEW, Figura 2.11.

13

Page 14: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 2.11: Configuracao para acesso ao banco de dados MySQL - Passo 2

O proximo passo, Figura 2.12, e inserir o Pool Name, que e o nome com o qual o servi-dor ira identificar a conexao com o banco de dados. No campo Resource Type selecione aopcao java.sql.Driver que indica que sera utilizado um driver JDBC para a conexao com obanco de dados. No segundo campo do item Database Driver Vendor, informe o caminhodo classpath para o driver JDBC do MySQL, que e: com.mysql.jdbc.Driver, para entaoacionar a opcao NEXT no topo da tela.

Figura 2.12: Configuracao para acesso ao banco de dados MySQL - Passo 3

Na proxima tela, conforme a Figura 2.13, selecione a opcao Ping ENABLE, para queo servidor Glassfish realize o teste da conexao com as configuracoes informadas.

14

Page 15: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 2.13: Configuracao para acesso ao banco de dados MySQL - Passo 4

Ainda na mesma interface, porem nas ultimas propriedades conforme a Figura 2.14,informe a string de conexao com o banco de dados no parametro URL e o usuario e senhaque foi configurado no banco de dados para o acesso. A string de conexao para o MySQLdeve seguir o seguinte padrao:

jdbc:mysql://localhost:3306/NOMEDOBANCO

Figura 2.14: Configuracao para acesso ao banco de dados MySQL - Passo 5

Para concluir esse processo, selecione a opcao FINISH nesta mesma tela, no fim dapagina.

O proximo passo e disponibilizar a conexao criada com o banco de dados como umrecurso disponıvel na aplicacao que sera desenvolvida. Para isso, como ilustra a Figura2.15, acesse a opcao RESOURCE ->JDBC ->JDBC RESOURCES e entao acione a opcaoNEW.

15

Page 16: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 2.15: Configuracao para acesso ao banco de dados MySQL - Passo 6

Na proxima interface, conforme a Figura 2.16, informe o JNDI Name e selecione aconexao no Pool Name. O JNDI Name pode seguir o seguinte padrao: jdbc/NOMEDA-CONEXAO. Para concluir, basta clicar na opcao OK no topo da interface.

Figura 2.16: Configuracao para acesso ao banco de dados MySQL - Passo 7

2.2 Instalacao e configuracao da IDE de desenvolvi-

mento - Adobe FLEX

MUITO IMPORTANTE: apenas execute os proximos passos se voce ira utilizar oAdobe Flex na camada de apresentacao do seu sistema, caso contrario pule para o capıtulo3.

16

Page 17: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Apos a instalacao e configuracao do servidor Glassfish, a instalacao e configuracao daIDE de desenvolvimento Eclipse juntamente com o plugin do Adobe Flex 4.6. O primeiropasso e realizar o download da instalacao do Eclipse pacote Eclipse IDE for Java EEDevelopers release INDIGO ou superior, que pode ser feito pelo site: www.eclipse.org.IMPORTANTE: faca o download do pacote compatıvel com a versao do JDKe JRE Java instalado em seu computador (32 bits ou 64 bits).

Para a instalacao da IDE Eclipse, basta apos o download, descompactar o arquivo .zipdentro de uma pasta do sistema operacional, sugere-se a pasta arquivos de programas,conforme a Figura 2.17.

Figura 2.17: Instalacao da IDE Eclipse for Java EE Developers

E importante que apos a conclusao do processo de descompactacao da IDE Eclipse,a mesma seja executada pelo menos uma vez para concluir o processo de instalacao,conforme a Figura 2.18.

Figura 2.18: IDE Eclipse for Java EE Developers

17

Page 18: Desenvolvimento de Sistemas Cliente - Servidor utilizando

O proximo passo e a instalacao do Adobe Flash Builder 4, sendo esta ferramentapode ser executada de duas formas, separada da IDE Eclipse onde sera desenvolvida alogica do sistema, ou integrada a mesma IDE Eclipse na forma de um plugin. Sugere-se trabalhar da segunda forma, para economia de recursos e simplificacao do processode desenvolvimento. Para tanto, como ilustra a Figura 2.19, devera ser executado oinstalador da ferramenta chamado: FlashBuilder 4 6 LS10.exe. Este arquivo pode serobtido atraves do site: https://freeriatools.adobe.com/. Na Figura 2.19, basta clicar naopcao ACEITAR o contrato de licenca para iniciar a instalacao.

Figura 2.19: Instalacao do Adobe Flash Builder

Na proxima tela do wizard de instalacao do Adobe Flash Builder 4, Figura 2.20,informe seu numero de licenca, ou selecione a opcao de versao de avaliacao. No idioma,sugere-se selecionar Ingles da America do Norte, e acionar a opcao avancar.

Figura 2.20: Instalacao do Adobe Flash Builder

18

Page 19: Desenvolvimento de Sistemas Cliente - Servidor utilizando

A proxima etapa do wizard, Figura fig:eclipse5, ilustra quais componentes serao ins-talados, para prosseguir, selecione a opcao INSTALAR.

Figura 2.21: Instalacao do Adobe Flash Builder

Aguarde ate a conclusao da instalacao como apresentado na Figura 2.22, e entaoexecute o Adobe Flash Builder 4 para concluir a instalacao.

(a) Conclusao da instalacao

(b) Execucao do Flash Builder 4

Figura 2.22: Instalacao do Adobe Flash Builder

19

Page 20: Desenvolvimento de Sistemas Cliente - Servidor utilizando

O proximo passo e a instalacao do Adobe Flash Builder como plugin da IDE Eclipsefor JEE Developers que foi instalada anteriormente. Para isso, conforme a Figura 2.23,acesse o diretorio: Arquivos de Programas (x86)\Adobe\Adobe Flash Builder 4.6\utilitiese execute o instalador: Adobe Flash Builder 4.6 Plug-in Utility.exe. IMPORTANTE:a instalacao deve ser executada em modo Administrador.

Figura 2.23: Instalacao do Plugin Adobe Flash Builder

O proximo passo, como ilustra a Figura 2.24, e iniciar a instalacao selecionando oidioma English, e acionando a opcao OK.

Figura 2.24: Instalacao do Plugin Adobe Flash Builder

O passo mais importante e o que segue, como na Figura 2.25, deve serinformado o diretorio onde o IDE Eclipse for JEE Developers foi descompac-tado.

20

Page 21: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 2.25: Instalacao do Plugin Adobe Flash Builder

Apos a conclusao da instalacao, sera apresenta a mensagem conforme a Figura 2.26.

Figura 2.26: Instalacao do Plugin Adobe Flash Builder

Para concluir a instalacao do plugin do Adobe Flash Builder 4, conforme a Figura2.27, e necessario executar o Eclipse for JEE Developers em modo de Administrador,para que o plugin possa ser habilitado. Caso este passo nao seja corretamente executado,o plugin nao sera instalado.

21

Page 22: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 2.27: Instalacao do Plugin Adobe Flash Builder

O ultimo passo necessario e a atualizacao do SDK do Adobe Flex 4. Para isso e ne-cessario realizar o download atraves do site: http://sourceforge.net/adobe/wiki/Projects/,do pacote flex sdk 4.6.0.23201B.zip ou superior. Apos realizar o download, o pacote de-vera ser descompactado dentro de um novo diretorio que devera ser criado em: Arquivosde Programas (x86)\Adobe\Adobe Flash Builder 4.6\sdks\ cujo nome sera 4.6.0.23201B.Todo o conteudo do arquivo zip, deve ser descompactado diretamente conforme a Figura2.28.

Figura 2.28: Instalacao do Plugin Adobe Flash Builder

Apos este processo, sera necessario configurar o IDE Eclipse for JEE Developers, ondeo plugin do Adobe Flash Builder 4 foi instalado, para reconhecer o novo SDK. Acesse aferramenta Eclipse e acione o menu: Window ->Preferences, conforme a Figura 2.29.

22

Page 23: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 2.29: Instalacao do Plugin Adobe Flash Builder

Na janela de Preferences, selecione a opcao Flash Builder ->Installed Flex SDKs. Najanela ao lado, acione a opcao Add, conforme a Figura 2.30.

Figura 2.30: Instalacao do Plugin Adobe Flash Builder

Uma janela de dialogo sera apresentada, como ilustra a Figura 2.31, informe no campoFlex SDK Location, o caminho completo onde o SDK foi descompactado, acione a opcaoOK para confirmar.

23

Page 24: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 2.31: Instalacao do Plugin Adobe Flash Builder

Por fim, como mostra a Figura 2.32, na tela anterior, selecione a nova versao do SDKFlex 4 e confirme no botao OK.

Figura 2.32: Instalacao do Plugin Adobe Flash Builder

24

Page 25: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Capıtulo 3

Desenvolvimento

3.1 Construcao da camada de negocio

Para iniciar o processo de desenvolvimento da aplicacao modelo vamos construir acamada de negocio, que ficara dentro do servidor Glassfish. Para isso, e importante quetoda a configuracao do ambiente descrita nas sessoes anteriores, esteja correta.

Para iniciar devemos configurar a IDE Eclipse for JEE Developers para considerar asbibliotecas do servidor Glassfish para a compilacao do projeto JEE. Para isso, selecionena tela principal da IDE Eclipse a opcao: Window ->Preferences, conforme a Figura ??.

Figura 3.1: Configuracao servidor JEE no IDE Eclipse

No proximo passo, como mostra a Figura 3.2, na janela Preferences selecionar no menua esquerda a opcao Server->Runtime Environments e entao na tela a direita acionar aoopcao ADD.

25

Page 26: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 3.2: Configuracao servidor JEE no IDE Eclipse - Preferences

Na janela de dialogo New Server Runtime Environment, conforme a figura 3.3, seleci-onar a opcao: Basic->J2EE Runtime Library e entao acionar a opcao Next.

26

Page 27: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 3.3: Configuracao servidor JEE no IDE Eclipse - New Server Runtime Environment

Na proxima tela de dialogo, no campo Name digite o nome do servidor Glasfish, nocampo Location informe o caminho ate a pasta com as bibliotecas do servidor JEE. Parao Glassfish deve informar o caminho: glassfish\modules, para entao confirmar no botaoFinish.

27

Page 28: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 3.4: Configuracao servidor JEE no IDE Eclipse - New Server Runtime Environment

Por fim, na janela de preferencias conforme ilustra a Figura 3.5, confirme a confi-guracao no botao OK.

28

Page 29: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 3.5: Configuracao servidor JEE no IDE Eclipse - Preferences

3.2 Implementando o projeto EJB

Os Enterprise Java Beans sao objetos Java que tem por objetivo conter a logicade negocio da aplicacao. Portanto estes objetos serao chamados pela aplicacao clientepara realizar as acoes concretas que definem a logica de funcionamento do sistema deinformacao. A principal vantagem na adocao deste tipo de arquitetura, e de possibilitarcom que, diferentes tipos de sistemas clientes, consumam estes objetos com a regra denegocio implementada na forma de servico, centralizando e possibilitando o aumento deescalabilidade da aplicacao simplesmente adicionando novos servidores JEE a um cluster.

Inicialmente vamos criar um EJB Project, para isso e importante trocar perspectivada IDE Eclipse para a Java EE, conforme a Figura 3.6. Entao basta acionar a opcao domenu: File->New->-EJB Project.

Figura 3.6: Criando projeto JEE

Na tela de wizard do novo Projeto EJB, Figura 3.7, digite no campo Project Nameo nome de seu projeto com a terminacao EJB, para que nos proximos passos facilite aidentificacao do mesmo, entao selecione o Target runtime para as bibliotecas do Glassfishque foram configuradas na IDE Eclipse, confirme a criacao do projeto na opcao Finish.

29

Page 30: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 3.7: Criando projeto JEE - New EJB Project

Observe, como o ilustrado na Figura 3.8, que a estrutura de um projeto EJB e diferentede um projeto Java Standard Edition. As classes EJB devem ser criadas dentro do sourcefolder ejbModule, para organizar nossas classes, crie dois packages chamados dao e ejbconforme a Figura 3.8.

30

Page 31: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 3.8: Estrutura de um projeto EJB

Para iniciar vamos criar as classes entity do sistema, essas classes sao POJOs (PlainOld Java Object) que consiste de classes Java com atributos encapsulados e metodosGETs e SETs, sendo que seu objetivo e trafegar dados da aplicacao Cliente para o Ser-vidor. Para isso vamos criar uma simples classe Cliente com alguns atributos, alem deencapsula-los criando os metodos GETs e SETs. Observe pela Figura 3.9, que a classe foicriada dentro do pacote dao Data Access Object, porque alem de servir como classe paratroca de informacoes entre a aplicacao Cliente e Servidor, ela tambem recebera anotacoesda JPA (Java Persistence API ), permitindo com que o provedor de persistencia do servi-dor Glassfish, realize automaticamente a persistencia desse objeto no banco de dados jaconfigurado.

31

Page 32: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 3.9: Exemplo de uma classe entity

Listing 3.1: Codigo Classe Cliente

package dao ;

import java . u t i l . Date ;

public class Cl i en t e {private St r ing nome ;private St r ing endereco ;private St r ing t e l e f o n e ;private int idade ;private Date dataNascimento ;

public St r ing getNome ( ) {return nome ;

}public void setNome ( St r ing nome) {

this . nome = nome ;}public St r ing getEndereco ( ) {

return endereco ;}public void setEndereco ( S t r ing endereco ) {

this . endereco = endereco ;}public St r ing ge tTe l e f one ( ) {

return t e l e f o n e ;}public void s e tTe l e f on e ( S t r ing t e l e f o n e ) {

this . t e l e f o n e = t e l e f o n e ;}

32

Page 33: Desenvolvimento de Sistemas Cliente - Servidor utilizando

public int getIdade ( ) {return idade ;

}public void s e t Idade ( int idade ) {

this . idade = idade ;}public Date getDataNascimento ( ) {

return dataNascimento ;}public void setDataNascimento (Date dataNascimento ) {

this . dataNascimento = dataNascimento ;}

}

Para realizar o mapeamento objeto relacional precisamos inicialmente inserir inserirum novo atributo na classe chamado OID, esse atributo sera a chave primaria e a ligacaoentre as instancias em memoria do objeto com as tuplas no banco de dados, sendo im-portante destacar que este atributo tambem deve ser encapsulado. A segunda alteracaoimportante e implementar a interface Serializable, visto que, este objeto devera ter a capa-cidade de ser serializado para que possa ser transmitido atraves de uma conexao de rede.O proximo passo e inserir as anotacoes JPA para realizar o mapeamento objeto-relacional,conforme a Figura 3.10, antes de definicao da classe, deve-se adicionar a anotacao Entityque indica a classe devera ser persistida no banco de dados. A anotacao Id e Genera-tedValue(strategy=GenerationType.IDENTITY) devem ser colocadas acima do atributoOID, indicando que ele servira de chave de ligacao entre as instancias do objeto e astuplas do banco de dados. Como temos um atributo do tipo java.util.Date, e impor-tante utilizar a anotacao Temporal(value=TemporalType.TIMESTAMP) para indicar aoprovedor de persistencia que esse atributo deve ser persistido como um campo TIMES-TAMP. IMPORTANTE: todas as anotacoes devem ser importadas do pacotejavax.persistence.*

Figura 3.10: Mapeamento objeto relacional

33

Page 34: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Listing 3.2: Classe entity com o mapeamento objeto-relacional

package dao ;

import java . i o . S e r i a l i z a b l e ;import java . u t i l . Date ;import javax . p e r s i s t e n c e . Ent ity ;import javax . p e r s i s t e n c e . GeneratedValue ;import javax . p e r s i s t e n c e . GenerationType ;import javax . p e r s i s t e n c e . Id ;import javax . p e r s i s t e n c e . Temporal ;import javax . p e r s i s t e n c e . TemporalType ;

@Entitypublic class Cl i en t e implements S e r i a l i z a b l e {

@Id@GeneratedValue ( s t r a t e gy=GenerationType . IDENTITY)private long oid ;private St r ing nome ;private St r ing endereco ;private St r ing t e l e f o n e ;private int idade ;@Temporal ( va lue=TemporalType .TIMESTAMP)private Date dataNascimento ;

public St r ing getNome ( ) {return nome ;

}public void setNome ( St r ing nome) {

this . nome = nome ;}public St r ing getEndereco ( ) {

return endereco ;}public void setEndereco ( S t r ing endereco ) {

this . endereco = endereco ;}public St r ing ge tTe l e f one ( ) {

return t e l e f o n e ;}public void s e tTe l e f on e ( S t r ing t e l e f o n e ) {

this . t e l e f o n e = t e l e f o n e ;}public int getIdade ( ) {

return idade ;}public void s e t Idade ( int idade ) {

this . idade = idade ;}

34

Page 35: Desenvolvimento de Sistemas Cliente - Servidor utilizando

public Date getDataNascimento ( ) {return dataNascimento ;

}public void setDataNascimento (Date dataNascimento ) {

this . dataNascimento = dataNascimento ;}public long getOid ( ) {

return oid ;}public void setOid ( long oid ) {

this . o id = oid ;}

}

O proximo passo e criar o codigo do arquivo XML persistence.xml, conforme a Lis-tagem 3.3, esse arquivo deve ser criado dentro do pacote META-INF, com o objetivode configurar qual Resource JDBC sera utilizado. Conforme a Figura 3.11, no TAGpersistence-unit define o nome como as classes EJB irao acessar ao banco de dados. Ja aTAG jta-data-source define o Resource JDBC que sera utilizado e foi definido conforme aFigura 2.15, informe o nome de acordo com o tipo de banco de dados que foi configuradoem seu ambiente.

Listing 3.3: Arquivo persistence.xml

<?xml version=” 1. 0 ” encoding=”UTF−8”?><p e r s i s t en c e>

< !−−Nome do c on t ex t o que c on f i g u r a o Provedor de P e r s i s t e n c i a −−><pe r s i s t enc e−uni t name=” ds i 2012con text ”>

<prov ide r>org . e c l i p s e . p e r s i s t en c e . jpa . Pe r s i s t en ceProv ide r</ prov ide r><j ta−data−source>jdbc /SqlServerConn</ jta−data−source><p r o pe r t i e s>

<property name=” e c l i p s e l i n k . ddl−generat i on ” value=” create−ta b l e s ”/><property name=” e c l i p s e l i n k . target−database ” value=”MYSQL”/><property name=” e c l i p s e l i n k . ddl−generat i on . output−mode” value=”database ” />

</ p r op e r t i e s></ p er s i s t en ce−uni t>

</ p e r s i s t e n c e>

Figura 3.11: Arquivo persistence.xml

Agora podemos criar nosso primeiro objeto EJB, para isso clique com o botao direitosobre o pacote ejb, e selecione ao opcao New->Session Bean (EJB 3.x), conforme a Figura3.12.

35

Page 36: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 3.12: Arquivo persistence.xml

No proximo passo do wizard, conforme a Figura 3.13, informe no campo Class nameo nome da classe, que deve terminar com sufixo Bean. No campo State type selecionea opcao Stateless, com isso, a cada invocacao dos metodos do objeto o estado (valoresdos atributos) do objeto nao sera mantido. No conjunto de parametros Create businessinterface, marque a opcao Remote e desmarque a opcao Local, com isso sera criado ainterface ejb.ClienteBeanRemote. Esta interface permite com que o objeto EJB possa serremotamente invocado pela aplicacao cliente, a classe EJB tem a estrutura conforme aFigura 3.14.

Figura 3.13: Arquivo persistence.xml

36

Page 37: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 3.14: Primeira classe EJB

Listing 3.4: Interface ClienteBeanRemote

package e jb ;

import javax . e jb . Remote ;

@Remotepublic interface ClienteBeanRemote {

}

Listing 3.5: Classe EJB ClienteBean

package e jb ;

import javax . e jb . S t a t e l e s s ;

/∗∗∗ Sess ion Bean implementat ion c l a s s ClienteBean∗/

@Sta t e l e s spublic class ClienteBean implements ClienteBeanRemote {

/∗∗∗ Defau l t cons t ruc to r .∗/

public ClienteBean ( ) {// TODO Auto−genera ted cons t ruc to r s tub

}

}

Para que nossa aplicacao cliente possa realizar o caso de uso Manter Cliente, seranecessario acessar a pelo menos 3 acoes basicas: listar todos os dados dos clientes, salvaros dados de um cliente (novo ou para atualizar os dados de um ja existente) e excluir osdados de um cliente do sistema. Para isso, devemos prover atraves da interface remota os

37

Page 38: Desenvolvimento de Sistemas Cliente - Servidor utilizando

metodos conforme a Figura 3.15. Todos os metodos criados nesta interface, poderao serchamados remotamente pela aplicacao cliente. Observe ainda na Figura 3.15, que aposalterar a interface Remote, a classe ClienteBean esta acusando erro porque ela nao estaimplementando os metodos criados na interface. Para solucionar este erro, conforme aFigura 3.16, basta abrir o codigo da classe ClienteBean, e clicar sobre a indicacao do erro,acionando a opcao para a geracao dos metodos que nao foram implementados, conformeo exemplo na Listagem 3.7.

Figura 3.15: Implementacao dos metodos base na interface Remote

Listing 3.6: Interface ClienteBeanRemote com os metodos de acesso

package e jb ;

import java . u t i l . L i s t ;import javax . e jb . Remote ;import dao . C l i en t e ;

@Remotepublic interface ClienteBeanRemote {

public void save ( C l i en t e c l i e n t e ) ;public List<Cl iente> g e tA l lC l i en t e ( ) ;public void remove ( C l i en t e c l i e n t e ) ;

}

Figura 3.16: Geracao dos metodos da interface Remote na classe Bean

38

Page 39: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Listing 3.7: Classe EJB ClienteBean, com os metodos implementados

package e jb ;

import java . u t i l . L i s t ;import javax . e jb . S t a t e l e s s ;import dao . C l i en t e ;

/∗∗∗ Sess ion Bean implementat ion c l a s s ClienteBean∗/

@Sta t e l e s spublic class ClienteBean implements ClienteBeanRemote {

/∗∗∗ Defau l t cons t ruc to r .∗/

public ClienteBean ( ) {// TODO Auto−genera ted cons t ruc to r s tub

}

@Overridepublic void save ( C l i en t e c l i e n t e ) {

// TODO Auto−genera ted method s tub

}

@Overridepublic List<Cl iente> g e tA l lC l i en t e ( ) {

// TODO Auto−genera ted method s tubreturn null ;

}

@Overridepublic void remove ( C l i en t e c l i e n t e ) {

// TODO Auto−genera ted method s tub

}

}

Agora precisamos iniciar a implementacao dos metodos dentro da classe ClenteBean,sendo que todos os metodos criados necessitam de acesso ao banco de dados, vamos realizara injecao de dependencia do provedor de persistencia. O que significa que daremos aoEJB ClienteBean, o acesso ao objeto EntityManager que e o responsavel por gerenciara persistencia dos objetos. E imporante destacar, conforme a Figura 3.17, ao utilizar aanotacao PersistenceContext e necessario informar a unitName, que deve ser a mesmadefinida no arquivo persistence.xml.

39

Page 40: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 3.17: Injecao de dependencia do provedor de persistencia

A implementacao do metodo save, ficara conforme a Figura 3.18, o metodo na primeiralinha verifica se o objeto recebido por parametro para ser persistido ja foi alguma vez salvono banco de dados, caso o metodo Find encontre o objeto ele sera passado para o metodoMerge que tem por objetivo persistir as alteracoes feitas nos dados do objeto sem criarum novo registro, portanto semelhante a instrucao SQL Update. Caso contrario, istoe o metodo find nao encontre o objeto, a instancia do objeto cliente sera passada porparametro para o metodo persist que ira inserir no banco de dados um novo registro pararepresentar o objeto, semelhante a instrucao SQL Insert, conforme a Listagem 3.8.

Figura 3.18: Implementacao do metodo SAVE

Listing 3.8: Trecho de codigo da classe ClienteBean, metodo save

@Overridepublic void save ( C l i en t e c l i e n t e ) {

i f (em . f i nd ( Cl i en t e . class , c l i e n t e . getOid ( ) ) != null ){//SQL: UPDATE C l i en t eem . merge ( c l i e n t e ) ;

}else {//SQL: INSERT INTO C l i en t eem . p e r s i s t ( c l i e n t e ) ;

}

}

O proximo metodo a ser implementado e o Remove, conforme a Figura 3.19, estemetodo ira receber uma instancia do objeto que deve ser removido do banco de dados.

40

Page 41: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Primeiramente o codigo verifica se o objeto a ser removido, ainda esta no banco de da-dos, recebendo do metodo find uma instancia do objeto Cliente atachada ao provedor depersistencia. Caso a referencia deste objeto nao tenha um valor nulo, ela e passada comoparametro para o metodo remove.

Figura 3.19: Implementacao do metodo REMOVE

Listing 3.9: Trecho de codigo da classe ClienteBean, metodo remove

@Overridepublic void remove ( C l i en t e c l i e n t e ) {

Cl i en t e cl iRemover =em . f i nd ( Cl i en t e . class , c l i e n t e . getOid ( ) ) ;

i f ( cl iRemover != null ){em . remove ( cl iRemover ) ;

}}

O ultimo metodo que precisa ser implementado e o que retornara uma consulta comtodos os clientes cadastrados no banco de dados. Para isso, precisamos criar uma queryde consulta ao banco de dados, sendo que esta query pode ser criada diretamente naclasse ClienteBean, porem e uma melhor pratica cria-la no objeto Entity na forma deuma NamedQuery. Para isso, conforme a Figura fig:JEEEclipse20, vamos alterar a classedao.Cliente, para inserir a anotacao NamedQueries criando a query queryAllClientes.

Figura 3.20: Implementacao de uma Query de consulta

Listing 3.10: Query EJBQL criada na classe Cliente

package dao ;

import java . i o . S e r i a l i z a b l e ;import java . u t i l . Date ;

41

Page 42: Desenvolvimento de Sistemas Cliente - Servidor utilizando

import javax . p e r s i s t e n c e . Ent ity ;import javax . p e r s i s t e n c e . GeneratedValue ;import javax . p e r s i s t e n c e . GenerationType ;import javax . p e r s i s t e n c e . Id ;import javax . p e r s i s t e n c e . NamedQueries ;import javax . p e r s i s t e n c e . NamedQuery ;import javax . p e r s i s t e n c e . Temporal ;import javax . p e r s i s t e n c e . TemporalType ;

@NamedQueries({@NamedQuery (name=” queryAl lC l i en t e s ” ,query=” S e l e c t c from Cl i en t e c” )

})

@Entitypublic class Cl i en t e implements S e r i a l i z a b l e {

@Id@GeneratedValue ( s t r a t e gy=GenerationType . IDENTITY)private long oid ;private St r ing nome ;private St r ing endereco ;private St r ing t e l e f o n e ;private int idade ;@Temporal ( va lue=TemporalType .TIMESTAMP)private Date dataNascimento ;

public St r ing getNome ( ) {return nome ;

}public void setNome ( St r ing nome) {

this . nome = nome ;}public St r ing getEndereco ( ) {

return endereco ;}public void setEndereco ( S t r ing endereco ) {

this . endereco = endereco ;}public St r ing ge tTe l e f one ( ) {

return t e l e f o n e ;}public void s e tTe l e f on e ( S t r ing t e l e f o n e ) {

this . t e l e f o n e = t e l e f o n e ;}public int getIdade ( ) {

return idade ;}public void s e t Idade ( int idade ) {

42

Page 43: Desenvolvimento de Sistemas Cliente - Servidor utilizando

this . idade = idade ;}public Date getDataNascimento ( ) {

return dataNascimento ;}public void setDataNascimento (Date dataNascimento ) {

this . dataNascimento = dataNascimento ;}public long getOid ( ) {

return oid ;}public void setOid ( long oid ) {

this . o id = oid ;}

}

Para finalizar a implementacao do metodo getAllCliente(), devemos retornar ao codigoda classe ClienteBean, conforme a Figura 3.21, inserindo o codigo para que o EntityMa-nager crie uma nova instancia do objeto Query, com base na NamedQuery definida noobjeto Entity, para entao executar o metodo getResultList() que por padrao retorna umalista de Clientes que devera ser retornada como resultado do metodo.

Figura 3.21: Implementacao do metodo getAllCliente

Listing 3.11: Trecho de codigo da classe ClienteBean, metodo getAllCliente

@Overridepublic List<Cl iente> g e tA l lC l i en t e ( ) {

Query q = em. createNamedQuery ( ” queryAl lC l i en t e s ” ) ;L i s t<Cl iente> c o l c l i e n t e s = q . g e tRe su l tL i s t ( ) ;return c o l c l i e n t e s ;

}

Com isso concluımos a construcao do objeto EJB ClienteBean para o funcionamentodas acoes basicas de uma tela de CRUD. A partir deste ponto, este material se divide emduas sessoes diferentes de implementacao: a primeira demonstra a implementacao de umaaplicacao cliente utilizando a tecnologia JSF, a segunda utiliza o Adobe Flex 4, a terceiraparte demonstra a criacao da mesma aplicacao utilizando Java e a API grafica SWING.

43

Page 44: Desenvolvimento de Sistemas Cliente - Servidor utilizando

3.3 Mapeamento Objeto Relacional - JPA (Java Per-

sistence API)

Neste ponto do processo voce ja possui uma classe onde o mapeamento objeto relacio-nal foi feito, a classe Cliente. Caso siga para a proxima secao, voce ira construir uma telade cadastro simples para esta classe. Porem voce pode optar por primeiro construir todoo mapeamento objeto relacional das classes do pacote DAO, ficando ao seu cargo essadecisao, mas o mapeamento precisa ser feito para que o sistema possa ser desenvolvido.

Toda aplicacao orientada a objetos tem o desafio de como persistir os dados arma-zenados nos objetos entity, sendo que, a solucao de utilizar Sistemas Gerenciadores deBancos de Dados relacionais ainda e a solucao mais adotada pelas empresas devido ocusto e principalmente pelo domınio da tecnologia de armazenamento de dados. Porem,os objetos nao podem ser simplesmente armazenados em tabelas de bancos relacionaisprincipalmente porque o paradigma orientado a objetos aceita que duas classes tenhamassociacoes muitos para muitos, ja o modelo da banco de dados relacional nao permiteessas associacoes devido a quebra das regras das formas normais. Para solucionar esseproblema utiliza-se uma camada de traducao entre o paradigma OO e o relacional co-nhecida como camada de persistencia que normalmente adota o padrao de mapeamentoobjeto relacional. Essa camada pode ser construıda manualmente, onde o programadorfica responsavel por ler a estrutura dos objetos de entidade e converter as modificacoesem seus atributos para instrucoes SQL que sincronizem o estado no banco de dados. Maspara simplificar o desenvolvimento este material ira utilizar a Java Persistence API (JPA)que foi implementada a partir da versao 3.0 da plataforma de desenvolvimento Enter-prise Java Beans e que pode tambem ser utilizada fora do contexto de um servidor deaplicacao, em uma plataforma JSE. Uma das grandes evolucoes da JPA a partir da versao3 do EJB, foi a adocao do conceito de ANOTACOES para definir como o mapeamentoobjeto relacional deve ser feito.

Para simplificar o entendimento de como realizar o mapeamento objeto relacional,vamos utilizar um exemplo de diagrama de domınio e entao construir as classes e realizaro mapeamento passo a passo. A Figura 3.22 ilustra as classes que serao consideradasneste exemplo.

Figura 3.22: Diagrama de Entidades do Projeto

A classe Cliente ja foi mapeada, nao apenas pelo exemplo do codigo anterior, maspor que e a melhor opcao de classe para iniciar esse processo, por ser uma classe quenao depende de nenhuma outra para existir. De forma simples nao possuir dependenciassignifica que ela nao esta associada a outras classes, o que pode gerar duvida ao analisaro diagrama e verificar que existe uma seta de associacao que liga Cliente a Pedido. Porem

44

Page 45: Desenvolvimento de Sistemas Cliente - Servidor utilizando

se observar-mos com atencao a classe Pedido que possui a navegabilidade para Cliente,desta forma a dependencia e de Pedido. Seguindo esta regra, a proxima classe que podeser mapeada de forma simples e a classe Produto. A listagem 3.12 apresenta o codigo daclasse Produto ja mapeada, mas algumas linhas precisam ser destacadas:

@Entity Esta anotacao indica para o JPA que a classe devera serpersistida em banco de dados, o que significa que seracriado uma tabela para representa-la.

Atributo OID Toda classe mapeada precisa ter um atributo que serviracomo chave primaria da tabela, sendo que neste modeloo atributo se chama OID (Object Identificator)

@Id Esta anotacao marca o atributo que esta abaixo delacomo chave primaria e unica do objeto na tabela debanco de dados. Sua funcao e associar as instanciasdos objetos em memoria com os diversos registros quepodem existir na tabela de banco de dados.

@GeneratedValue Indica para o JPA qual sera a estrategia de geracao dachave primaria que sera adotada pelo banco de dados(neste caso utiliza-se chamos de auto incremento)

@Column Esta anotacao serve para modificar caracterısticas co-muns de qualquer atributo ao ser criado no banco dedados como coluna de uma tabela, no caso da linha deexemplo, adicionou-se a caracterıstica de chave unicapara o campo codigo, uma vez que ele nao e a PK databela mas tambem precisa ser unico por ser um campoinformado pelo usuario.

Atributos do tipo String E importante lembrar que todos os atributos Stringserao criados no banco como colunas do tipo varcharcom 255 caracteres, desta forma, caso o campo exisjaum numero maior de caracteres e necessario inserir aanotacao @Column setando a propiedade length

GET e SET Todos os atributos da classe entity precisam ter metodosGET e SET gerados para parmitir que o JPA possa aces-sar os atributos da classe e os carregar com dados queforam consultados no banco.

Listing 3.12: Classe Produto

package dao ;

import javax . p e r s i s t en c e . Column ;import javax . p e r s i s t en c e . Ent i ty ;import javax . p e r s i s t en c e . GeneratedValue ;import javax . p e r s i s t en c e . GenerationType ;import javax . p e r s i s t en c e . Id ;

@Entitypublic class Produto {

@Id@GeneratedValue( s t ra t egy=GenerationType . IDENTITY)private long oid ;@Column( unique=true )private int cod igo ;@Column( l ength=10000)private St r i ng de s c r i c ao ;private f loat va l or ;

public long getOid ( ) {return oid ;

}public void setOid ( long oid ) {

this . o id = oid ;}public int getCodigo ( ) {

return cod igo ;}

45

Page 46: Desenvolvimento de Sistemas Cliente - Servidor utilizando

public void setCodigo ( int cod igo ) {this . cod igo = codigo ;

}public St r i ng getDesc r i cao ( ) {

return de s c r i c ao ;}public void s e tDe s c r i c ao ( S t r i ng de s c r i c ao ) {

this . d e s c r i c ao = de s c r i c ao ;}public f loat getValor ( ) {

return va l or ;}public void s e tVa l or ( f l oat va l or ) {

this . va l or = va l or ;}

}

Para dar continuidade ao mapeamento objeto relacional, vamos fazer o mapeamentodas classes Pedido - ItemPedido e Produto. Essas classes precisam ser mapeadas emconjunto porque geram dependencias entre elas, uma vez que o pedido tem uma associacaocom itens de pedido e por consequencia itens de pedido se associa com produto. Vamoscomecar com a classe Pedido e Item de Pedido, criando as classes, e incluindo as anotacoesmınimas para o mapamento alem de gerar os metodos GETs e SETs.

Listing 3.13: Classe Pedido

@Entitypublic class Pedido {

@Id@GeneratedValue( s t ra t egy=GenerationType . IDENTITY)private long oid ;@Temporal( value=TemporalType .TIMESTAMP)private Date dataEmissao ;private boolean conc lu i do ;private Cl i en te c l i e n t ePed ido ;

// Segue aba i xo c o d i go dos metodos GETs e SETs . . .

O mesmo foi feito com a classe Item de Pedido, criando apenas os atributos basicos egerando os GETs e SETs.

Listing 3.14: Classe Pedido

@Entitypublic class ItemPedido {

@Id@GeneratedValue( s t ra t egy=GenerationType . IDENTITY)private int oid ;private int quantidade ;private f loat valorItem ;

// Segue aba i xo c o d i go dos metodos GETs e SETs

Voltamos a trabalha com a classe Pedido, a primeira associacao que vamos fazer eentre a classe Pedido e Cliente, como pode ser observado no diagrama um Pedido tem umCliente responsavel por solicita-lo ja um Cliente pode solicitar muitos Pedidos desta forma,vamos inserir a anotacao @ManyToOne sobre o atributo Cliente. Importante destacar queno caso de associacoes sempre e importante definir o efeito cascata das acoes realizadascom a classe principal. Neste caso selecionamos dois efeitos MERGE e REFRESH quesignificam que quando a classe Pedido sofrer um UPDATE no banco ou um SELECT, osdados do cliente (caso necessario) tambem serao atualizados ou novamente recuperadosdo banco de dados.

Listing 3.15: Classe Pedido associacao com Cliente

@Entitypublic class Pedido {

@Id@GeneratedValue( s t ra t egy=GenerationType . IDENTITY)private long oid ;@Temporal( value=TemporalType .TIMESTAMP)private Date dataEmissao ;private boolean conc lu i do ;@ManyToOne( cascade={CascadeType .MERGE, CascadeType .REFRESH})private Cl i en te c l i e n t ePed ido ;

// Segue aba i xo c o d i go dos metodos GETs e SETs . . .

46

Page 47: Desenvolvimento de Sistemas Cliente - Servidor utilizando

A proxima associacao sera entre a classe Pedido e Item de Pedido, sendo esta amais comum mas que exigem mais atencao, pois se trata da associacao um para mui-tos. Primeiro vamos alterar a classe pedido criando um atributo do tipo colecao, trata-sede um java.util.ArrayList, porem o atributo deve ser criado utilizando uma interfacejava.util.List, desta forma o JPA compreende que existe uma associacao entre duas clas-ses e nao que o atributo colItensPedido e um simples tipo objeto que seria armazenado nobanco no formato serializado. O proximo passo e utilizar a anotacao @OneToMany (umpara muitos) com a opcao de cascata de eventos ALL porque caso um pedido sofra umainclusao, alteracao ou ate exclusao, todas essas acoes devem ser propagadas para os Itensdo Pedido mantendo o banco de forma ıntegra. Ainda foi inclusa a anotacao @JoinCo-lumn para indicar que nao se deseja a criacao de uma tabela associativa no banco de dadosentre Pedido e ItemPedido, observa-se que o name indica o nome da chave extrangeira natabela ItemPedido que sera criada. NAO ESQUECA DE GERAR OS GETS E SETS :)

Listing 3.16: Classe Pedido associacao com Item de Pedido.

@Entitypublic class Pedido {

@Id@GeneratedValue( s t ra t egy=GenerationType . IDENTITY)private long oid ;@Temporal( value=TemporalType .TIMESTAMP)private Date dataEmissao ;private boolean conc lu i do ;@ManyToOne( cascade={CascadeType .MERGE, CascadeType .REFRESH})private Cl i en te c l i e n t ePed ido ;@OneToMany( cascade=CascadeType .ALL)@JoinColumn(name=”Pedido oid ” )private List<ItemPedido> co l I t en sPed ido = new ArrayList<ItemPedido >() ;

// Segue aba i xo c o d i go dos metodos GETs e SETs . . .

E importante neste ponto realizar o deploy da aplicacao no servidor para verificar senao ha nenhum erro de digitacao e se as tabelas sao criadas corretamente no banco dedados.

Para concluir vamos trabalhar no mapeamento da classe Produto em relacao a classeItem de Pedido. Primeiro vamos criar a classe Produto e incluir as anotacoes mınimasnecessarias.

Listing 3.17: Classe Produto

@Entitypublic class Produto implements S e r i a l i z a b l e {

@Id@GeneratedValue( s t ra t egy=GenerationType . IDENTITY)private long oid ;@Column( unique=true )private int cod igo ;@Column( l ength=10000)private St r i ng de s c r i c ao ;private f loat va l or ;

// Segue aba i xo c o d i go dos metodos GETs e SETs . . .

Para associar esta classe Produto ao Item de Pedido retornamos ao item e incluımosum novo atributo produtoItem do tipo produto, e ao analisar o diagrama observamos quenovamente temos uma associacao do tipo @ManyToOne (muitos itens de pedido para umproduto). NAO ESQUECA DE GERAR OS GETS E SETS, e entao realizar o deploy daaplicacao.

Listing 3.18: Classe Item de Pedido associada a Produto

@Entitypublic class ItemPedido {

@Id@GeneratedValue( s t ra t egy=GenerationType . IDENTITY)private int oid ;private int quantidade ;private f loat valorItem ;@ManyToOne( cascade={CascadeType .MERGE, CascadeType .REFRESH})private Produto produtoItem ;

47

Page 48: Desenvolvimento de Sistemas Cliente - Servidor utilizando

// Segue aba i xo c o d i go dos metodos GETs e SETs

3.4 Implementando a aplicacao cliente em JSF - Java

Server Faces

O JSF (Java Server Faces) e uma tecnologia da Oracle que permite a construcaode interfaces WEB server-side com base em bibliotecas de TAGs xHTML que injetamcodigo HTML, simplificando a construcao de componentes complexos para o ambienteWEB. Essa tecnologia e uma evolucao do JSP (Java Server Pages) e dos Servlets queforam a primeira plataforma Java para construcao de interfaces WEB server-side. Paraconstrucao de aplicacoes utilizando o JSF e necessaria a criacao de um novo projeto naIDE Eclipse do tipo Dynamic Web Project conforme a Figura 3.23, para isso basta acessaro menu da IDE Eclipse File->New->Dynamic Web Project.

Figura 3.23: Criacao do projeto Dynamic Web Project

Na janela de dialogo para a criacao do novo projeto do tipo Dynamic Web Project,e necessario informar o nome do projeto onde e sugerido colocar o sufixo ”WEB”parafacilitar o reconhecimento do projeto dentro da IDE Eclipse, como ilustrado na Figura3.24. E importante selecionar qual o Target Runtime que nada mais e do que o servidorJEE que sera utilizado para a publicacao da aplicacao. Acione a opcao Finish.

48

Page 49: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 3.24: Configuracao do projeto Dynamic Web Project

O projeto criado tem uma estrutura similar a apresentada na Figura 3.25. Na pastaJava Resource serao inseridas as classes Java que irao controlar a interface grafica doprojeto. A pasta WebContent ira abrigar todos os arquivos XHTML, imagens, folhasde estilo CSS e demais componentes de uma interface Web comum. A subpasta WEB-INF/lib ira receber todas as bibliotecas externas necessarias para o desenvolvimento daaplicacao como o JSF. Ainda dentro da pasta WEB-INF serao criados arquivos XML paraa configuracao do comportamento da aplicacao.

49

Page 50: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 3.25: Estrutura do projeto Web

O proximo passo e realizar o download das bibliotecas JavaServer Faces (JSF) Mo-jarra, que e a implementacao de referencia da Oracle para essa tecnologia e da bibliotecaauxiliar PrimeFaces. Para realizar o download do JSF Mojarra basta acessar o linkhttp://javaserverfaces.java.net/download.html, conforme a figura 3.26, e buscar pelo ar-quivo javax.faces-2.2.7.jar (ou versao mais recente) que pode ser baixado diretamente pelolink:

https://maven.java.net/content/repositories/releases/org/glassfish/javax.faces/2.2.7/javax.faces-2.2.7.jar.Esta versao e exigida por ter compabilidade com o servidor JEE Glassfish 4.0.

Figura 3.26: Download do JSF Mojarra

50

Page 51: Desenvolvimento de Sistemas Cliente - Servidor utilizando

A proxima biblioteca que precisa ser feito o download e o Prime Faces, que e umcojunto de TAGs XHTML que aceleram o desenvolvimento WEB dando acesso ao usode componentes graficos ricos em interfaces WEB, ilustrado pela Figura 3.27. Por exem-plo, essa biblioteca permite a criacao de grids de consulta de dados com mecanismos depaginacao e filtros de forma automatica, bastando apenas algumas configuracoes. O down-load pode ser realizado pelo endereco http://www.primefaces.org/downloads.html ondedeve ser realizado o download da versao Community 3.1.1 que esta no arquivo primefaces-5.0.jar no link: http://repository.primefaces.org/org/primefaces/primefaces/5.0.RC1/primefaces-5.0.RC1.jar

Figura 3.27: Download do Prime Faces

Os arquivos javax.faces-2.2.7.jar e primefaces-5.0.jar (ou superior) deverao ser coloca-dos na pastas WEB-INF/lib conforme mostra a Figura 3.28. A simples copia dos arquivosJAR para esta pasta ja os coloca disponıvel para uso no projeto, nao havendo necessidadede mais nenhuma configuracao adicional.

51

Page 52: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 3.28: Inclusao das bibliotecas no projeto WEB - utilize versoes atualizadas

Agora que as bibliotecas ja foram importadas o proximo passo e a configuracao doprojeto WEB para que suporte as caracterısticas de um projeto utilizando a tecnologiaJavaServer Faces. Com isso, a IDE Eclipse habilitara diversas novas opcoes que facilitamo desenvolvimento de interfaces nesta tecnologia. Para isso voce deve clicar com o botaodireito do mouse sobre o projeto WEB e acessar a opcao Properties. Na janela de dialogoProject Properties, selecione a opcao Project Facets e marque a opcao JavaServer Facesselecionando a opcao 2.0 como mostra a Figura 3.29.

Figura 3.29: Configuracao dos Facets do Eclipse para JSF

52

Page 53: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Ainda na mesma tela, selecione a opcao Further configuration available.... Comoilustra a Figura 3.30, na opcao JSF Implementation Library Type: Disable Library Con-figuration. Desta forma o projeto ira utilizar as bibliotecas que foram copiadas para apasta META-INF/lib. Ainda nesta tela na opcao URL Mapping Patterns, remova todosos itens e adicione um novo contendo apenas a string *.xhtml. Com isso, todos os arqui-vos .xhtml serao considerados arquivos com codigo JSF e interpretados pelo compiladorJava. Confirme as configuracoes no botao OK.

Figura 3.30: Configuracao dos Facets do Eclipse para JSF

Observer como ilustra a Figura 3.31 que no projeto foi criado um novo arquivo META-INF/faces-config.xml, esse arquivo configura o comportamento da aplicacao utilizando atecnologia JSF. Com isso a configuracao para utilizar a tecnologia JSF esta concluıda.

53

Page 54: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 3.31: Arquivo XML de configuracao do JavaServer Faces

Como na arquitetura proposta para esse projeto sera utilizado um servidor com umconteiner JEE, as paginas JSF deverao chamar metodos os EJBs para realizar as acoesprevistas na logica de negocio do sistema. Para isso ser possıvel, precisamos criar umadependencia entre os projetos WEB e EJB. Entao clique com o botao direito do mousesobre o projeto WEB e selecione a opcao Properties, como ilustra a Figura 3.32. Na opcaoJava Build Path, selecione a aba Projects e acione o botao ADD.

Figura 3.32: Configuracao de dependencia entre projetos WEB e EJB

Na janela de dialogo Required Project Selection, como mostra a Figura 3.33, selecioneo projeto EJB e confirme no botao OK. Isso torna as classes EJB pertencentes ao processode compilacao do projet WEB permitindo a realizacao do acesso remoto aos objetos peloprocesso de lookup e a chamada remota de metodos.

54

Page 55: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 3.33: Configuracao de dependencia entre projetos WEB e EJB

Para finalizar, precisamos modificar o projeto DSI2012Server para que o projetoDSI2012WEB tambem seja incluıdo no processo de compilacao e montagem do pacoteEAR que e enviado para o servidor Glassfish. Para isso, clique com o botao direito sobreo projeto DSI2012Server e selecione a opcao properties. Na tela apresentada na Figura3.34, selecione a opcao Deployment Assembly e acione o botao ADD.

55

Page 56: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 3.34: Configuracao do Enterprise Application para compilacao e deploy do projeto WEB

Na proxima janela, ilustrada pela Figura 3.35, o projeto WEB sera vinculado a mon-tagem do arquivo EAR. Na janela (a) selecione o tipo do objeto que sera vinculado aoprojeto, neste caso um Project, selecione a opcao NEXT. Na proxima janela (b) selecioneo projeto WEB dentro da lista de projetos do Eclipse, entao no final, o projeto WEB seraapresentado na lista bastando apenas confirmar com o botao OK.

56

Page 57: Desenvolvimento de Sistemas Cliente - Servidor utilizando

(a) Selecionando o tipo do projeto

(b) Vinculando o projeto WEB

(c) Montagem do arquivo EAR

Figura 3.35: Configuracao da montagem do arquivo EAR

57

Page 58: Desenvolvimento de Sistemas Cliente - Servidor utilizando

3.4.1 Iniciando o desenvolvimento de um cadastro simples com

JSF

Para iniciar o desenvolvimento, como mostra a Figura 3.36, precisamos criar uma novainterface no projeto EJB do tipo LOCAL. Esse passo e necessario, porque na introducaodo desenvolvimento com EJB, foi criada apenas uma interface do tipo REMOTE. Destamaneira qualquer invocacao dos EJBs utilizar a interface de rede para comunicacao entreo cliente e o objeto remoto no servidor. Ao criar a interface do tipo LOCAL, permitimosque a conexao ocorra diretamente entre o HTTP Container e o EJB Container do servidorEJB.

Figura 3.36: Criacao da interface LOCAL

A criacao da interface comeca por clicar com o botao direito do mouse sobre o pacoteejb dentro do projeto DSI2012EJB, e selecionar a opcao NEW Interface. Para mantero padrao informe o nome da interface como: ClienteBeanLocal. Utilize o codigo abaixocomo base para a interface.

Listing 3.19: Codigo da interface ClienteBeanLocal

package e jb ;

import java . u t i l . L i s t ;import javax . e jb . Loca l ;import dao . C l i en t e ;

@Localpublic interface ClienteBeanLocal {

58

Page 59: Desenvolvimento de Sistemas Cliente - Servidor utilizando

public void save ( C l i en t e c l i e n t e ) ;public List<Cl iente> g e tA l lC l i en t e ( ) ;public void remove ( C l i en t e c l i e n t e ) ;

}

O proximo passo e modificar o codigo da classe ClienteBean para que ela assine tambemimplemente a interface ClienteBeanLocal, conforme e ilustrado pela Figura 3.37.

Figura 3.37: Implementacao da interface Local pelo EJB

Agora podemos iniciar o desenvolvimento do projeto, vamos retornar ao projeto DSI2012WEBconforme a Figura 3.38.

Figura 3.38: Iniciando a implementacao WEB

Vamos comecar criando a classe que ira controlar os eventos gerados na inteface decadastro de um Cliente. Para isso clique com o botao direito sobre a pasta SRC dentroda pasta Java Resources do projeto WEB, e crie um novo pacote chamado control, comomostra a Figura 3.39.

59

Page 60: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 3.39: Criando o pacote control no projeto WEB

O proximo passo e criar neste pacote, uma nova classe cujo nome sera CrtCliente.Utilize o codigo de exemplo abaixo. Observe que a classe e marcada com a anotacao@ManageBean, isso significa que este objeto sera responsavel por controlar os eventose podera ser referenciado pelo nome crtCliente em qualquer pagina JSF. A marcacao@SessionScoped significa que os valores de todos os atributos das classes serao mantidosem memoria (instancia do objeto control) durante o tempo que a sessao entre o navegadordo usuario e o servidor se mantenham ativas. O atributo clienteBeanLocal foi marcadocom a anotacao @EJB, com isso, o container EJB ira injetar uma instancia do objetoremoto ClienteBean que e um EJB dentro deste atributo, dando acesso direto a todos osmetodos do objeto remoto. Isso pode ser notado pelo codigo do metodo getAllClientes()que simplesmente chama um metodo do EJB para realizar uma consulta no banco dedados.

Listing 3.20: Codigo da classe CrtCliente controle da interface

package con t r o l ;

import java . u t i l . L i s t ;import javax . e jb .EJB;import javax . f a c e s . bean .ManagedBean ;

60

Page 61: Desenvolvimento de Sistemas Cliente - Servidor utilizando

import javax . f a c e s . bean . Sess ionScoped ;import dao . C l i en t e ;import e jb . Cl ienteBeanLocal ;

@ManagedBean(name=” c r tC l i e n t e ” )@SessionScopedpublic class CrtCl i ente {

@EJBprivate ClienteBeanLocal c l i en t eBeanLoca l ;private Cl i en t e model ;

public Cl i en t e getModel ( ) {return model ;

}

public void setModel ( C l i en t e model ) {this . model = model ;

}

public List<Cl iente> g e tA l lC l i e n t e s ( ){return c l i en t eBeanLoca l . g e tA l lC l i en t e ( ) ;

}}

O proximo passo e implementar a interface grafica em JSF para a tela principal docadastro de Cliente, sendo que esta tela tera basicamente um GRID que ira listar osregistros. Para isso clique com o botao direito sobre a pasta WebContent e selecione aopcao New, HTML File, conforme a Figura 3.40.

Figura 3.40: Criando uma interface WEB JSF

Na janela de dialogo para criacao do novo arquivo HTML, conforme a Figura 3.41,informe o nome do arquivo como FrmCliente.xhtml e pressione a opcao NEXT.

61

Page 62: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 3.41: Criando a interface em XHTML

Na proxima etapa desta janela de dialogo, a IDE Eclipse apresenta alguns padroesiniciais de arquivos no formato XHTML. Como mostra a Figura 3.42, selecione a opcaoHTML 5 e acione a opcao Finish.

62

Page 63: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 3.42: Criando a interface em XHTML

Para iniciar o desenvolvimento utilizando JSF, precisamos alterar o tag HTML parainclusao dos namespaces que darao acesso as TAG libs do JSF. Tambem e muito impor-tante alterar a tag HEAD para utilizar a tag do namespace ”h”, desta maneira o JSFira injetar os codigos necessarios no HEAD para que o tema grafico do JSF possa sercarregado, como e mostrado na Figura 3.43.

Figura 3.43: Codigo basico do JSF

63

Page 64: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Listing 3.21: FrmCliente.xhml

< !DOCTYPE html><html xmlns=” h t tp : //www.w3 . org /1999/ xhtml”

xmlns :u i=” h t tp : // java . sun . com/ j s f / f a c e l e t s ”xmlns:h=” h t tp : // java . sun . com/ j s f /html”xmlns : f=” h t tp : // java . sun . com/ j s f / core ”xmlns:p=” h t tp : // pr ime fa ce s . org / u i ”>

<h:head><meta cha r se t=”UTF−8”/>< t i t l e>I n s e r t t i t l e here</ t i t l e></h:head>

<body>

</body></html>

Para que o grid possa ser apresentado, devemos inserir o TAG dataTable que receberaalguns parametros para configurar seu acesso aos dados. O parametro value faz uma cha-mada ao metodo getAllClientes() da classe de controle, sendo essa a origem dos registrosqeu serao apresentados. O parametro var indica o nome da variavel onde cada instanciado objeto que estiver na lista sera gravado para permitir a configuracao das colunas doGRID. O parametro selectionMode indica quais regras de selecao de registros serao apli-cadas a este grid. O parametro selection indica que ao selecionar uma linha, a referenciado objeto que representa esta linha sera automaticamente atribuıda ao atributo crtCli-ente.model permitindo com que esse objeto possa ser acessado para identifica-lo. Dentroda TAG dataTable sao criados conjuntos da TAG column para configurar cada colunaque sera apresentado no GRID e qual atributo do objeto Cliente sera apresentado nestacoluna.

Listing 3.22: Implementando um GRID no FrmCliente.xhml

< !DOCTYPE html><html xmlns=” h t tp : //www.w3 . org /1999/ xhtml”

xmlns :u i=” h t tp : // java . sun . com/ j s f / f a c e l e t s ”xmlns:h=” h t tp : // java . sun . com/ j s f /html”xmlns : f=” h t tp : // java . sun . com/ j s f / core ”xmlns:p=” h t tp : // pr ime fa ce s . org / u i ”>

<h:head><meta cha r se t=”UTF−8”/>< t i t l e>I n s e r t t i t l e here</ t i t l e></h:head>

<body><h:form>

<p :pane l header=”Manter C l i en t e s ”><p:dataTable va lue=”#{c r tC l i e n t e . g e tA l lC l i e n t e s ( )} ”var=” c l i e n t e ” se l ect ionMode=” s i n g l e ”

64

Page 65: Desenvolvimento de Sistemas Cliente - Servidor utilizando

s e l e c t i o n=”#{c r tC l i e n t e . model}” rowKey=”#{c l i e n t e . o id }”>< f : f a c e t name=”header ”>Li s ta de C l i en t e s</ f : f a c e t><p:column>

< f : f a c e t name=”header ” >CPF</ f : f a c e t><h:outputText value=”#{ c l i e n t e .CPF}”/>

</p:column><p:column>

< f : f a c e t name=”header ” >Nome</ f : f a c e t><h:outputText value=”#{ c l i e n t e . nome}”/>

</p:column><p:column>

< f : f a c e t name=”header ” >Idade</ f : f a c e t><h:outputText value=”#{ c l i e n t e . idade}”/>

</p:column></ p:dataTable>

</ p :pane l></h:form>

</body></html>

Apos implementar este codigo, realize o processo de deploy exportando o arquivo EARdo projeto DSI2012Server, e acesse pelo navegador o enderecohttp://localhost:8080/DSI2012WEB/FrmCliente.xhtmle verifique se e apresentada a interface conforme a Figura 3.44.

Figura 3.44: Interface de GRID no JSF

3.4.2 Implementando formularios no JavaServer Pages

Para criar o formulario devemos alterar a pagina FrmCliente.xhtml inserindo o codigopara apresentar o botao incluir posicionado logo abaixo do grid, que ao ser clicado, abrapara o usuario uma dialog, dando a impressao ao usuario de que e uma janela, conformea Figura 3.45.

65

Page 66: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 3.45: Implementando uma dialog

Observe que foi inserido um novo TAG chamado commandButton que cria no layoutum botao com o texto Incluir. Ao ser clicado ele dispara o evento show por JavaScriptdo objeto dlg1 que foi criado logo abaixo. A TAG dialog cria uma janela que sera semprereferenciada pelo codigo JavaScript pelo nome definido no atributo widgetVar que nestecaso foi dlg1. E importante destacar que a dialog que contem o formularioprecisa ficar dentro de um novo tag FORM cujo id e form. A TAG panelGrid euma especie de gerenciador de layout que permite facilmente a disposicao dos campos noformato de tabela com duas colunas conforme o atributo columns.

O proximo passo e inserir um formulario com os campos dentro do panelGrid. Paracada campo sera utilizado as TAGs outputLabel e inputText para compor os campos doformulario, como mostra a Figura 3.46, repita esse par de TAGs para todos os campos doobjeto Entity. Observe que no TAG inputText existe um parametro chamado value, nelefoi utilizada o conceito de biding entre o componente visual e o objeto model criado dentrodo controle. O binding pode ser entendido como uma amarracao entre o componente visuale o objeto, sempre que o objeto sofrer uma atualizacao do seu estado automaticamenteo campo visual sera atualizado e o mesmo ocorre inversamente do campo visual para oobjeto. Esse trecho de codigo termina com a criacao de dois botoes no formulario OK eCancelar, ambos possuem por enquanto apenas a acao de fechar a dialog.

66

Page 67: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 3.46: Codigo do formulario

O codigo completo para iniciar o formulario fica conforme a listagem 3.23.

Listing 3.23: Implementando o formulario na FrmCliente.xhml

< !DOCTYPE html><html xmlns=” ht tp : //www.w3 . org /1999/ xhtml”

xmlns:u i=” ht tp : // java . sun . com/ j s f / f a c e l e t s ”xmlns:h=” ht t p : // java . sun . com/ j s f /html”xmln s : f=” ht t p : // java . sun . com/ j s f / core ”xmlns:p=” ht t p : // p r ime face s . org / u i ”>

<h:head><meta char se t=”UTF−8”/>< t i t l e>I n s e r t t i t l e here</ t i t l e></h:head>

<h:body>

<h:form>

<p :pane l header=”Manter C l i e n t e s ”><p:dataTable id=”dataTable”

value=”#{c r tC l i e n t e . g e tA l lC l i e n t e s ()} ”var=” c l i e n t e ” se l ect ionMode=” s i n g l e ”s e l e c t i o n=”#{c r tC l i e n t e . model}”rowKey=”#{c l i e n t e . oid}”>< f : f a c e t name=”header ”>L i s ta de Cl i e n te s</ f : f a c e t>

<p:column>< f : f a c e t name=”header ” >CPF</ f : f a c e t>

<h:outputText value=”#{ c l i e n t e .CPF}”/></p:column><p:column>

< f : f a c e t name=”header ” >Nome</ f : f a c e t><h:outputText value=”#{ c l i e n t e . nome}”/>

</p:column><p:column>

< f : f a c e t name=”header ” >Idade</ f : f a c e t><h:outputText value=”#{ c l i e n t e . idade}”/>

</p:column>< f : f a c e t name=” f o o t e r ”>

<p:commandButton value=” I n c l u i r ” id=” cb I n c l u i r ”update=” : fo rm: formDeta i l ”i con=”ui−icon−ex t l i nk ” oncomplete=”PF( ’ dlg1 ’ ) . show () ”/>

</ f : f a c e t></ p:dataTable>

</ p :pane l></h:form>

<h:form id=”form”><p :d i a l o g width=”500” he i gh t=”300” id=” d e t a i lD i a l o g ” modal=” true ”

header=”Detalhe do Cl i en te ” widgetVar=”dlg1 ”><h:panelGrid id=” formDetai l ” columns=”2”>

<h:outputLabel name=”lblCPF” value=”CPF” /><p: inputText id=”txtCPF” l a b e l=” lblCPF”

value=”#{c r tC l i e n t e . model .CPF}” />

<h:outputLabel name=”lblNome” value=”Nome” /><p: inputText id=”txtNome” l a b e l=” lblNome”

value=”#{c r tC l i e n t e . model . nome}” />

<h:outputLabel name=” lb l Id ad e ” value=” Idade” /><p: inputText id=” txtIdade ” l ab e l=” lb l Idade ”

value=”#{c r tC l i e n t e . model . idade}” />

<p:commandButton value=”OK”oncomplete=”PF( ’ dlg1 ’ ) . h ide ( ) ” id=”cbOK”/>

67

Page 68: Desenvolvimento de Sistemas Cliente - Servidor utilizando

<p:commandButton value=”Cancelar ” id=”cbCancelar ”oncomplete=”PF( ’ dlg1 ’ ) . h ide ( ) ” />

</ h:panelGrid></ p : d i a l o g>

</h:form>

</h:body></html>

Agora que o formulario esta pronto precisamos modificar nossa classe control para rea-lizar o codigo necessario para criar um novo cliente e inserir no banco de dados. Conformemostra a Figura 3.47, primeiro vamos alterar nossa variavel model e inicializa-la com umanova instancia da classe Cliente, isso e importante porque o processo de Binding entreos campos do formulario e o atributo model exige que a variavel tenha uma referenciapara um objeto instanciado. Precisamos tambem criar dois metodos createNewCliente()que ira simplesmente criar uma nova instancia de Cliente no atributo model e o metodosaveCliente() que ira enviar a referencia do objeto para o EJB realizar a persistencia domesmo.

Figura 3.47: Codigo do botao inserir

Agora precisamos retornar a classe EJB ClienteBean no projeto SERVER para revero codigo dos metodos: save() e remove(), caso o seu codigo esteja identico ao exemploapresentado na Figura 3.48, voce nao precisa realizar nenhuma alteracao a mais. O JSFnao consegue manter o contexto do EJB porque a configuracao do EJB ClienteBean tem aanotacao @Stateless. Desta forma, o metodo contains da classe EntityManager sempre iraretornar FALSE caso um objeto seja passado por parametro para verificar se ele ja existeou nao no contexto de persistencia, isso gera um problema ao executar um UPDATEnos dados do objeto pois ele sempre ira criar um novo registro no banco de dados e naoapenas atualizar os dados do objeto. Para solucionar esse problema, devemos alterar osmetodos save() e remove() para que sempre verifiquem atraves do metodo FIND se oobjeto recebido por parametro para persistencia ja existe no banco de dados/contexto depersistencia ou nao. Com isso, o codigo nao ira duplicar objetos no banco de dados. Omesmo e feito no metodo remove() pois o EntityManager so consegue remover objetos queestejam sendo controlados pelo contexto de persistencia, por isso ne necessario utilizar ometodo FIND para recuperar uma instancia do objeto que esteja sendo gerenciada.

68

Page 69: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 3.48: Correcao no codigo do EJB ClienteBean

Ja podemos alterar nossa interface FrmCliente.xhtml para chamar os metodos da classecontrol. Como mostra a Figura 3.49, devemos alterar a primeira TAG FORM para incluirum atributo chamado id com o valor formTable, isso e importante porque, apos concluira inclusao e persistencia de um novo Cliente, precisamos disparar um evento para que adataTable atualize seus dados e apresente o novo registro. A segunda alteracao necessariae no botao Incluir, vamos inserir um novo atributo chamado value e vincular atraves deum binding a chamada do metodo createNewCliente para a classe de controle. Destaforma ao ser acionado o botao ira chamar o metodo que instancia um novo cliente noatributo model da classe control e assim, os campos do formulario serao automaticamentelimpos para que o usuario possa digitar os dados.

Figura 3.49: Executando o metodo incluir

Para concluir a rotina de incluir, devemos alterar agora o codigo da FrmCliente.xhtmlno botao OK e Cancelar do formulario que esta na dialog. Como ilustra a Figura 3.50,no TAG do commandButton OK foi inserido o atributo action que atraves do processo

69

Page 70: Desenvolvimento de Sistemas Cliente - Servidor utilizando

de binding ira executar o metodo save para enviar os dados do objeto atribuıdo no modelpara a persistencia pelo EJB. Repare que nao e necessario atualizar os atributos do objetoreferenciado pelo model um a um como e feito em uma interface Swing pois o mecanismode binding ja realiza esse processo. Tanto no commandButton OK quanto no Cancelar enecessario incluir um novo atributo update e referenciar o id do formulario onde esta adataTable, entao ao acionar qualquer um dos dois botoes, o grid sera automaticamenteatualizado. Apos concluir essas modificacoes realize o processo de deploy da aplicacao everifique se o cadastro permite a inclusao de novos registros.

Figura 3.50: Executando o metodo salvar

Agora podemos trabalhar na opcao de alterar um registro cadastrado, para isso, bastaalterar novamente nossa tela FrmCliente.xhtml como mostra a Figura 3.51 e inserir dentroda TAG dataTable um novo commandButton para a opcao alterar. Observe que ele emuito semelhante ao botao incluir, a unica diferenca e que ele nao executa o metodo cre-ateNewCliente, simplesmente abre a dialog e solicita sua atualizacao. Isso ocorre porquea dataTable possui um atributo chamado selection onde foi realizado o binding para aatualizacao do atributo model da classe control. Como todos os campos do formulariotambem estao ligados em binding com esse atributo model, ao selecionar um item nadataTable o componente automaticamente seta o objeto respectivo no atributo model eo formulario da dialog ja tem acesso aos dados. Ao clicar no botao alterar, a dialog como formulario e apresentada em tela e os dados do objeto selecionado sao apresentados aousuario para alteracao. O usuario altera os campos necessarios no formulario e pressionao botao OK, que ja esta preparado para chamar o metodo save que persiste as alteracoesnos dados. Basta realizar um deploy da aplicacao para verificar o funcionamento.

70

Page 71: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 3.51: Implementando a opcao alterar

Para concluir o cadastro, precisamos implementar a opcao para remover um registroselecionado. Ao acionar essa opcao e necessario apresentar uma tela de confirmacao paraque o usuario confirme se realmente deseja excluir esse registro. Para isso precisamos in-cluir um novo commandButton no dataTable como e apresentado na Figura 3.52, observeque este botao ao ser executado abre a dialog dlgRemove que tambem precisa ser inseridana FrmCliente.xhtml. O codigo da dialog remover deve ser inserido logo apos o fecha-mento da TAG form da dataTable. Essa nova dialog ira apenas apresentar a pergunta seo usuario deseja realmente excluir o registro e dois commandButtons OK e Cancelar.

Figura 3.52: Implementando a opcao remover

Caso o usuario clique no botao OK, o metodo remove da classe control sera executadoe a Figura 3.53 apresenta a sua implementacao. O metodo simplesmente ira passar areferencia do atributo model para o metodo remove do EJB ClienteBean e esse seraresponsavel por remover o objeto do banco de dados. Para testar o funcionamento bastarealizar o deploy da aplicacao.

71

Page 72: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 3.53: Codigo no control para opcao remover

3.4.3 Implementando associacao entre classes

O proximo passo do desenvolvimento e modificar o cadastro de Cliente para incluiruma associacao com a classe Cidade conforme mostra a figura 3.54.

Figura 3.54: Diagrama de classes

Primeiro devemos criar a classe Cidade dentro do projeto EJB no pacote dao, estaclasse tem como objetivo armazenar dados de uma cidade conforme mostra o codigo dalistagem 3.24.

Listing 3.24: Codigo da classe Cidade

package dao ;

import java . i o . S e r i a l i z a b l e ;

72

Page 73: Desenvolvimento de Sistemas Cliente - Servidor utilizando

import javax . p e r s i s t e n c e . Ent ity ;import javax . p e r s i s t e n c e . GeneratedValue ;import javax . p e r s i s t e n c e . GenerationType ;import javax . p e r s i s t e n c e . Id ;import javax . p e r s i s t e n c e . NamedQueries ;import javax . p e r s i s t e n c e . NamedQuery ;

@NamedQueries({@NamedQuery (name=”queryAl lCidades ” ,

query=” S e l e c t c from Cidade c” )})

@Entitypublic class Cidade implements S e r i a l i z a b l e {

@Id@GeneratedValue ( s t r a t e gy=GenerationType . IDENTITY)private int oid ;private St r ing cidade ;private St r ing estado ;

public int getOid ( ) {return oid ;

}public void setOid ( int oid ) {

this . o id = oid ;}public St r ing getCidade ( ) {

return c idade ;}public void setCidade ( St r ing cidade ) {

this . c idade = cidade ;}public St r ing getEstado ( ) {

return estado ;}public void setEstado ( St r ing estado ) {

this . estado = estado ;}

}

Uma vez criada a classe Cidade devemos modificar o codigo da classe Cliente pararealizar a associacao entre as classes DAO, isso e feito criando um novo atributo na classee inserindo a anotacao ManyToOne, como e mostrado na figura 3.55.

73

Page 74: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 3.55: Associacao entre a classe Cliente e Cidade

O proximo passo e criar um formulario JSF para cadastrar a Cidade seguindo o mesmopadrao implementado da classe Cliente. Como o processo e identico ao descrito no topicoanterior, segue os codigos necessarios para a implementacao da tela. O primeiro passoe criar a interface LOCAL dentro do pacote bean no projeto EJB conforme o codigo dalistagem 3.25.

Listing 3.25: Codigo da Interface Local para o Bean

package e jb ;

import java . u t i l . L i s t ;import javax . e jb . Loca l ;import dao . C l i en t e ;

@Localpublic interface ClienteBeanLocal {

public void save ( C l i en t e c l i e n t e ) ;public List<Cl iente> g e tA l lC l i en t e ( ) ;public void remove ( C l i en t e c l i e n t e ) ;

}

O proximo passo e implementar o EJB atraves da classe Cliente Bean contendo osmetodos basicos de save, remove e getAll conforme a listagem 3.26.

Listing 3.26: Codigo da classe EJB

package e jb ;

import java . u t i l . L i s t ;import javax . e jb . S t a t e l e s s ;import javax . p e r s i s t e n c e . EntityManager ;import javax . p e r s i s t e n c e . Pers i s t enceContext ;import javax . p e r s i s t e n c e . Query ;import dao . Cidade ;

/∗∗∗ Sess ion Bean implementat ion c l a s s CidadeBean∗/

@Sta t e l e s s

74

Page 75: Desenvolvimento de Sistemas Cliente - Servidor utilizando

public class CidadeBean implements CidadeBeanLocal {

/∗∗∗ Defau l t cons t ruc to r .∗/

@Pers istenceContext ( unitName=” ds i 2012cont ext” )private EntityManager em ;

public CidadeBean ( ) {}

@Overridepublic void save ( Cidade cidade ) {

i f (em . f i nd ( Cidade . class , c idade . getOid ( ) ) != null ){em . merge ( c idade ) ;

}else {em . p e r s i s t ( c idade ) ;

}}

@Overridepublic List<Cidade> getAl lCidade ( ) {

Query q = em. createNamedQuery ( ” queryAl lCidades ” ) ;L i s t<Cidade> co lCidades = q . g e tRe su l tL i s t ( ) ;return co lCidades ;

}

@Overridepublic void remove ( Cidade cidade ) {

c idade = em . f i nd ( Cidade . class , c idade . getOid ( ) ) ;i f ( c idade != null ){

em . remove ( c idade ) ;}

}

}

Agora no projeto WEB, vamos implementar dentro do pacote control a classe decontrole do formulario de cadastro de cidades, conforme a listagem 3.27.

Listing 3.27: Classe de controle CrtCidade

package con t r o l ;

import java . u t i l . L i s t ;import javax . e jb .EJB;import javax . f a c e s . bean .ManagedBean ;import javax . f a c e s . bean . Sess ionScoped ;import dao . Cidade ;import e jb . CidadeBeanLocal ;

75

Page 76: Desenvolvimento de Sistemas Cliente - Servidor utilizando

@ManagedBean(name=” crtCidade ” )@SessionScopedpublic class CrtCidade {

@EJBprivate CidadeBeanLocal cidadeBeanLocal ;private Cidade model = new Cidade ( ) ;

public void createNewCidade ( ){model = new Cidade ( ) ;

}

public void remove ( ){i f (model != null )

cidadeBeanLocal . remove (model ) ;}

public void saveCidade ( ){cidadeBeanLocal . save (model ) ;

}

public Cidade getModel ( ) {return model ;

}

public void setModel ( Cidade model ) {this . model = model ;

}

public List<Cidade> getAl lCidades ( ){return cidadeBeanLocal . getAl lCidade ( ) ;

}}

Por fim, vamos implementar a interface em JSF para permitir o cadastro de umacidade conforme o codigo apresentado na listagem 3.28.

Listing 3.28: Implementando o formulario na FrmCidade.xhml

< !DOCTYPE html><html xmlns=” h t tp : //www.w3 . org /1999/ xhtml”

xmlns :u i=” h t tp : // java . sun . com/ j s f / f a c e l e t s ”xmlns:h=” h t tp : // java . sun . com/ j s f /html”xmlns : f=” h t tp : // java . sun . com/ j s f / core ”xmlns:p=” h t tp : // pr ime fa ce s . org / u i ”>

<h:head><meta cha r se t=”UTF−8”/>< t i t l e>I n s e r t t i t l e here</ t i t l e></h:head>

76

Page 77: Desenvolvimento de Sistemas Cliente - Servidor utilizando

<h:body><h:form id=” formTable”><p :pane l header=”Manter Cidade”><p:dataTable id=”dataTable ”value=”#{crtCidade . getAl lCidades ( )} ”var=” cidade ” se l ect ionMode=” s i n g l e ”s e l e c t i o n=”#{crtCidade . model}”rowKey=”#{c idade . o id }”>< f : f a c e t name=”header ”>Li s ta de Cidade</ f : f a c e t><p:column>

< f : f a c e t name=”header ” >Cidade</ f : f a c e t><h:outputText value=”#{c idade . c idade }”/>

</p:column><p:column>< f : f a c e t name=”header ” >Estado</ f : f a c e t><h:outputText value=”#{c idade . estado }”/>

</p:column>< f : f a c e t name=” f o o t e r ”><p:commandButton value=” I n c l u i r ” id=” cb I n c l u i r ”update=” : f o rm: f o rmDeta i l ”i con=”ui−icon−e x t l i n k ” oncomplete=”PF( ’ dlg1 ’ ) . show ( ) ”ac t i on=”#{crtCidade . createNewCidade}”/>

<p:commandButton value=”Al t e ra r ” id=” cbAlterar ”update=” : f o rm: f o rmDeta i l ” i con=”ui−icon−e x t l i n k ”oncomplete=”PF( ’ dlg1 ’ ) . show ( ) ”/>

<p:commandButton value=”Exc lu i r ” id=” cbExc lu i r ”i con=”ui−icon−e x t l i n k ” oncomplete=”PF( ’ dlgRemove ’ ) . show ( ) ”/>

</ f : f a c e t></p:dataTable>

</ p :pane l></h:form>

<p : d i a l o g width=”500” he ight=”50” id=” removeDialog ”modal=” true ” header=”Confirma exc lu s a o do r e g i s t r o ?”widgetVar=”dlgRemove”>

<h:form id=”formRemove”><h:pane lGr id columns=”2”><h:commandButton ac t i on=”#{crtCidade . remove}”

update=” : formTable” value=”OK” /><h:commandButton immediate=” true ”

update=” : formTable” value=”Cancel ” /></ h :pane lGr id>

</h:form>

</ p : d i a l o g><h:form id=”form”><p : d i a l o g width=”500” he ight=”300” id=” d e t a i lD i a l o g”

modal=” true ” header=”Detalhe da Cidade”widgetVar=”dlg1 ”>

77

Page 78: Desenvolvimento de Sistemas Cliente - Servidor utilizando

<h:pane lGr id id=” formDeta i l ” columns=”2”><h:outputLabel name=” lb lCidade ” value=”Cidade” /><p: inputText id=” txtCidade ” l a b e l=” lb lCidade ”

value=”#{crtCidade . model . c idade }” /><h:outputLabel name=” lb lEstado ” value=”Estado” /><p: inputText id=” txtEstado ” l a b e l=” lb lEstado ”

value=”#{crtCidade . model . estado }” /><p:commandButton value=”OK”

oncomplete=”PF( ’ dlg1 ’ ) . h ide ( ) ” id=”cbOK”act i on=”#{crtCidade . saveCidade}”update=” : formTable”/>

<p:commandButton value=”Cancelar ” id=” cbCancelar ”oncomplete=”PF( ’ dlg1 ’ ) . h ide ( ) ” update=” : formTable”/>

</ h :pane lGr id></ p : d i a l o g>

</h:form>

</h:body></html>

Efetue o deploy da aplicacao e realize o acesso ao FrmCidade.xhtml, conforme ilustraa Figura 3.56 o formulario de cadastro de cidade deve ser apresentado.

Figura 3.56: Formulario de cadastro de Cidade

Agora devemos implementar o campo de combobox dentro do cadastro de clientes.Mas antes precisamos preparar um conjunto de classes para que o JSF consiga gerenciar aassociacao entre as classes de forma automatica. O primeiro passo e modificar o codigo daclasse entity dao.Cidade para implementar os metodos equals e hashcode, esse processoe importante para permitir que as APIs do JSF consigam identificar os objetos de formaunica. Para gerar esse codigo abra o codigo da classe dao.Cidade no projeto SERVER eclique com o botao direito sobre uma linha em branco do codigo da classe e selecione aopcao SOURCE ->Generate hashCode() and equals()... como mostra a Figura 3.57.

78

Page 79: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 3.57: Gerando o codigo dos metodos equals e hashcode - passo 1

Na interface que sera apresentada, conforme a Figura 3.58, selecione apenas o campoOID e confirme no botao OK. Com isso o codigo gerado para os dois metodos sera baseadona chave artificial criada pela camada de persistencia, garantindo uma identificacao unicapara o objeto.

Figura 3.58: Gerando o codigo dos metodos equals e hashcode - passo 2

O codigo da classe devera ficar semelhante ao apresentado na Listagem 3.29.

Listing 3.29: Metodos hashcode e equals da classe Cidade

package dao ;

79

Page 80: Desenvolvimento de Sistemas Cliente - Servidor utilizando

import java . i o . S e r i a l i z a b l e ;import javax . p e r s i s t e n c e . Ent ity ;import javax . p e r s i s t e n c e . GeneratedValue ;import javax . p e r s i s t e n c e . GenerationType ;import javax . p e r s i s t e n c e . Id ;import javax . p e r s i s t e n c e . NamedQueries ;import javax . p e r s i s t e n c e . NamedQuery ;

@NamedQueries({@NamedQuery (name=”queryAl lCidades ” ,query=” S e l e c t c from Cidade c” )

})

@Entitypublic class Cidade implements S e r i a l i z a b l e {

@Id@GeneratedValue ( s t r a t e gy=GenerationType . IDENTITY)private int oid ;private St r ing cidade ;private St r ing estado ;

@Overridepublic int hashCode ( ) {

f ina l int prime = 31 ;int r e s u l t = 1 ;r e s u l t = prime ∗ r e s u l t + oid ;return r e s u l t ;

}@Overridepublic boolean equa l s ( Object obj ) {

i f ( this == obj )return true ;

i f ( obj == null )return fa l se ;

i f ( g e tC la s s ( ) != obj . g e tC la s s ( ) )return fa l se ;

Cidade other = ( Cidade ) obj ;i f ( o id != other . o id )

return fa l se ;return true ;

}public int getOid ( ) {

return oid ;}public void setOid ( int oid ) {

this . o id = oid ;}

80

Page 81: Desenvolvimento de Sistemas Cliente - Servidor utilizando

public St r ing getCidade ( ) {return c idade ;

}public void setCidade ( St r ing cidade ) {

this . c idade = cidade ;}public St r ing getEstado ( ) {

return estado ;}public void setEstado ( St r ing estado ) {

this . estado = estado ;}

}

Agora vamos preparar nossa classe de controle do FrmCliente (CrtCliente) para con-trolar o componente combobox (no JSF chamado de selectOneMenu). Coforme a Figura3.59, primeiro devemos inserir a injecao do EJB CidadeBeanLocal no atributo cidadeBe-anLocal, importante lembrar que para cada EJB deve haver uma anotacao @EJB sobreo atributo para sinalizar a necessidade de realizar o lookup do objeto remoto. Aindaconforme a mesma figura, vamos criar uma colecao utilizando o tipo List <Cidade >parao atributo colCidades, esse atributo ira armazenar as instancias da classe Cidade que seraapresentada em tela. Devemos tambem criar um novo metodo nesta classe chamado load-Data(), observe que esse metodo recebe a anotacao PostConstruct, com isso, este metodosera invocado automaticamente pela API do JSF logo apos a classe CrtCliente ser instan-ciada em memoria, seu codigo tem por objetivo executar o metodo getAllCidade() do EJBCidadeBean e adicionar esses objetos a colecao colCidades. Uma importante observacaoe que a colecao recebida pelo metodo de consulta nao deve ser diretamente atribuıda aoatributo colCidades, para evitar que a colecao modifique seu estado durante o tempo devida do ManagedBean devido as funcionalidades o JPA, pois essa caracterıstica, podeprovocar erros no funcionamento do componente. Por fim, devemos construir o metodogetColCidades que sera atribuıdo ao componente atraves do processo de Binding paraprover os dados que serao apresentados pelo componente.

Figura 3.59: Modificando a classe CrtCliente para suportar a associacao com outra classe

O proximo passo e implementar a classe que ira converter as instancias da classe

81

Page 82: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Cidade para um formato que permita o gerenciamento dos itens pela API do JSF. Essaclasse deve implementar a interface javax.faces.convert.Converter com isso ira receber doismetodos: o primeiro (getAsObject) e responsavel por converter uma representacao noformato String para o objeto que sera gerenciado pelo componente (neste caso a classeCidade), observe que o codigo sugerido recebe o valor em String pelo parametro arg2,converte a String para o tipo Integer e o utiliza como ındice para acessar a colecao de Ci-dades que esta no CrtCliente; o segundo metodo (getAsString) faz o trabalho inverso aometodo anterior, portanto, converte a referencia de um objeto (Cidade) em um valor queo represente para identifica-lo dentro da colecao, neste caso utilizamos o metodo indexOfpara retornar o numero do ındice que representa a posicao onde esta esse objeto dentroda colecao.Pode-se observar ainda nesta mesma classe que existe uma anotacao ManagedProperty(value= ”#crtCliente”), essa anotacao permite que se crie uma dependencia entre ManagedBe-ans, assim, e possıvel acessar valores desses objetos, bastando alem da anotacao criar ummetodo SET.A listagem 3.30 apresenta o codigo da classe Converter.

Listing 3.30: Classe Converter para controlar os objetos do selectOneMenu

package con t r o l ;

import java . i o . S e r i a l i z a b l e ;import javax . f a c e s . bean .ManagedBean ;import javax . f a c e s . bean . ManagedProperty ;import javax . f a c e s . bean . RequestScoped ;import javax . f a c e s . component . UIComponent ;import javax . f a c e s . context . FacesContext ;import javax . f a c e s . conver t . Converter ;

@ManagedBean(name=” cidadeConverter ” )@RequestScopedpublic class CidadeConverter

implements Converter , S e r i a l i z a b l e {@ManagedProperty( va lue = ”#{c r tC l i e n t e }” )private CrtCl i ente c r tC l i e n t e ;

@Overridepublic Object getAsObject ( FacesContext arg0 ,UIComponent arg1 , S t r ing arg2 ) {

int po s i t i o n = In t eg e r . pa r se In t ( arg2 ) ;return c r tC l i e n t e . getColCidades ( ) . get ( p o s i t i o n ) ;

}

@Overridepublic St r ing getAsStr ing ( FacesContext arg0 ,UIComponent arg1 , Object arg2 ) {

return St r ing . valueOf ( c r tC l i e n t e .getColCidades ( ) . indexOf ( arg2 ) ) ;

82

Page 83: Desenvolvimento de Sistemas Cliente - Servidor utilizando

}

public void s e tCr tC l i en t e ( CrtCl i ente c r tC l i e n t e ) {this . c r tC l i e n t e = c r tC l i e n t e ;

}}

Para concluir agora devemos modificar o formulario JSF para incluir o componenteSelectOneMenu conforme o codigo da Figura 3.60. Logo apos o label Cidade colocado como componente outputLabel, e inserido um grupo de TAGs iniciando pelo p:selectOneMenuque e o componente combobox. Alem do atributo ID, e definido o atributo value realizandoum binding para o objeto model do formulario como os demais campos, e e informado oatributo converter para apontar para o ManagedBean que ira realizar esta acao. Dentrodo TAG selectOneMenu e criado um TAG selectItens que ira fornecer a colecao de objetospara preencher o componente. Neste TAG sao passados valores para os atributos: value- recebe um binding para o metodo getColCidades() de onde sera obtido a colecao deobjetos para preencher as opcoes da lista; var - para definir o nome da variavel querepresenta um item da colecao; itemLabel - utilize-se o processo de binding para definirqual atributo sera apresentado em tela pelo componente para representar uma instanciado objeto; itemValue - da mesma forma utilizando o processo de binding, define-se qualsera o valor que cada item recebera para ser representado (neste caso como foi informadoa variavel item, o objeto Converter ira converter a referencia do objeto para o numero daposicao dele dentro da colecao de Cidades recebido do objeto CidadeBean permitindo asua identificacao).A Figura 3.60 apresenta o codigo resultante. Apos concluir essa acao realize o deploy doaplicativo para testar o funcionamento.

Figura 3.60: Inserindo o componente SelectOneMenu no formulario

3.4.4 Implementando um cadastro pai-filho

O cadastro pai-filho consiste de uma tela CRUD mais complexa onde diversos objetossao instanciados criando uma relacao de todo-parte. A Figura 3.61 apresenta o diagramade classes do exemplo que sera descrito a seguir, vamos utilizar a aplicacao classica depedido com itens de pedido para demonstrar a implementacao. Observe pelo diagrama

83

Page 84: Desenvolvimento de Sistemas Cliente - Servidor utilizando

que a classe pedido possui uma associacao com a classe Cliente e que a classe Item dePedido possui uma associacao com a classe Produto.

Figura 3.61: Diagrama de classes do cadastro pai-filho

Caso voce tenha seguido exatamente este material, voce ja deve ter implementado ocadastro de Cliente faltando implementar apenas o cadastro de Produto. Como se trata deum cadastro simples e muito parecido com os demais cadastros ja descritos nesse material,segue o codigo fonte completo para sua implementacao. Conforme a Listagem 3.31 a classedeve ser criada no projeto Server no pacote dao, observe que ja foi implementada umaNamedQuery que sera utilizada tanto na tela de cadastro para alimentar o grid com osprodutos quanto no campo combobox no cadastro de pedido na forma de classe associativa,da mesma forma, importante ja implementar os metodos equals e hashcode.

Listing 3.31: Classe entity dao.Produto

package dao ;

import java . i o . S e r i a l i z a b l e ;

import javax . p e r s i s t e n c e . Column ;import javax . p e r s i s t e n c e . Ent ity ;import javax . p e r s i s t e n c e . GeneratedValue ;import javax . p e r s i s t e n c e . GenerationType ;import javax . p e r s i s t e n c e . Id ;import javax . p e r s i s t e n c e . NamedQueries ;import javax . p e r s i s t e n c e . NamedQuery ;

@NamedQueries({

84

Page 85: Desenvolvimento de Sistemas Cliente - Servidor utilizando

@NamedQuery (name=”queryAl lProdutos ” ,query=” S e l e c t p from Produto p” )

})

@Entitypublic class Produto implements S e r i a l i z a b l e {

@Id@GeneratedValue ( s t r a t e gy=GenerationType . IDENTITY)private int oid ;@Column( unique=true )private St r ing codigo ;private St r ing de s c r i c a o ;private St r ing unidade ;private f loat valorCompra ;private f loat valorVenda ;private St r ing f o rnecedo r ;

@Overridepublic int hashCode ( ) {

f ina l int prime = 31 ;int r e s u l t = 1 ;r e s u l t = prime ∗ r e s u l t + oid ;return r e s u l t ;

}@Overridepublic boolean equa l s ( Object obj ) {

i f ( this == obj )return true ;

i f ( obj == null )return fa l se ;

i f ( g e tC la s s ( ) != obj . g e tC la s s ( ) )return fa l se ;

Produto other = ( Produto ) obj ;i f ( o id != other . o id )

return fa l se ;return true ;

}public int getOid ( ) {

return oid ;}public void setOid ( int oid ) {

this . o id = oid ;}public St r ing getCodigo ( ) {

return codigo ;}public void setCodigo ( S t r ing codigo ) {

this . codigo = codigo ;

85

Page 86: Desenvolvimento de Sistemas Cliente - Servidor utilizando

}public St r ing ge tDesc r i cao ( ) {

return de s c r i c a o ;}public void s e tDe s c r i c a o ( S t r ing de s c r i c a o ) {

this . d e s c r i c a o = de s c r i c a o ;}public St r ing getUnidade ( ) {

return unidade ;}public void setUnidade ( St r ing unidade ) {

this . unidade = unidade ;}public f loat getValorCompra ( ) {

return valorCompra ;}public void setValorCompra ( f loat valorCompra ) {

this . valorCompra = valorCompra ;}public f loat getValorVenda ( ) {

return valorVenda ;}public void setValorVenda ( f loat valorVenda ) {

this . valorVenda = valorVenda ;}public St r ing getFornecedor ( ) {

return f o rnecedo r ;}public void setFornecedor ( S t r ing f o rnecedo r ) {

this . f o rnecedo r = fo rnecedo r ;}

}

Ainda no projeto server voce devera implementar o EJB responsavel por controlar asacoes sobre o produto, a Listagem 3.32 apresenta a interface local para o EJB com osmetodos padroes de uma tela de cadastro, que deve ser colocada no pacote ejb.

Listing 3.32: Interface local ProdutoBeanLocal

package e jb ;

import java . u t i l . L i s t ;import javax . e jb . Loca l ;import dao . Produto ;

@Localpublic interface ProdutoBeanLocal {

public void save ( Produto produto ) ;public List<Produto> getAl lProduto ( ) ;

86

Page 87: Desenvolvimento de Sistemas Cliente - Servidor utilizando

public void remove ( Produto produto ) ;public Produto findByKey ( int oid ) ;

}

Agora devemos implementar no projeto server no pacote ejb a classe que efetivamentee o EJB conforme a listagem 3.33. Observe que o codigo e muito parecido com o codigoja implementado nas demais telas de cadastro.

Listing 3.33: Classe EJB ProdutoBean

package e jb ;

import java . u t i l . L i s t ;import javax . e jb . S t a t e l e s s ;import javax . p e r s i s t e n c e . EntityManager ;import javax . p e r s i s t e n c e . Pers i s t enceContext ;import javax . p e r s i s t e n c e . Query ;import dao . Produto ;

@Sta t e l e s spublic class ProdutoBean implements ProdutoBeanLocal {

@Pers istenceContext ( unitName=” ds i 2012cont ext” )private EntityManager em ;

public ProdutoBean ( ) {// TODO Auto−genera ted cons t ruc to r s tub

}

@Overridepublic void save ( Produto produto ) {

i f (em . f i nd ( Produto . class , produto . getOid ( ) ) != null ){em . merge ( produto ) ;

}else {em . p e r s i s t ( produto ) ;

}}

@Overridepublic List<Produto> getAl lProduto ( ) {

Query q = em. createNamedQuery ( ” queryAl lProdutos ” ) ;L i s t<Produto> co lProdutos = q . g e tRe su l tL i s t ( ) ;return co lProdutos ;

}

@Overridepublic void remove ( Produto produto ) {

produto = em. f i nd ( Produto . class , produto . getOid ( ) ) ;i f ( produto !=null ){

em . remove ( produto ) ;

87

Page 88: Desenvolvimento de Sistemas Cliente - Servidor utilizando

}}

@Overridepublic Produto findByKey ( int oid ) {

return em . f i nd ( Produto . class , o id ) ;}

}

Agora no projeto WEB devemos implementar a classe de controle para o cadastro deprodutos, observe o codigo na Listagem 3.34.

Listing 3.34: Classe control CrtProduto

package con t r o l ;

import java . u t i l . ArrayList ;import java . u t i l . L i s t ;

import javax . e jb .EJB;import javax . f a c e s . bean .ManagedBean ;import javax . f a c e s . bean . Sess ionScoped ;import dao . Produto ;import e jb . ProdutoBeanLocal ;

@ManagedBean(name=” crtProduto” )@SessionScopedpublic class CrtProduto {

@EJBprivate ProdutoBeanLocal produtoBeanLocal ;private List<Produto> co lProdutos = new ArrayList<Produto >() ;private Produto model = new Produto ( ) ;

public void createNewProduto ( ){model = new Produto ( ) ;

}public void remove ( ){

i f (model != null )produtoBeanLocal . remove (model ) ;

}public void saveProduto ( ){

produtoBeanLocal . save (model ) ;}public List<Produto> getAl lProdutos ( ){

return produtoBeanLocal . getAl lProduto ( ) ;}

88

Page 89: Desenvolvimento de Sistemas Cliente - Servidor utilizando

public List<Produto> getColProdutos ( ) {return co lProdutos ;

}public void setColProdutos ( L i s t<Produto> co lProdutos ) {

this . co lProdutos = colProdutos ;}public Produto getModel ( ) {

return model ;}public void setModel ( Produto model ) {

this . model = model ;}

}

Por fim, ainda no projeto WEB, vamos implementar o formulario em xHTML para ocadastro de Produtos conforme a Listagem 3.35.

Listing 3.35: Implementando o formulario na FrmProduto.xhml

< !DOCTYPE html><html xmlns=” h t tp : //www.w3 . org /1999/ xhtml”

xmlns :u i=” h t tp : // java . sun . com/ j s f / f a c e l e t s ”xmlns:h=” h t tp : // java . sun . com/ j s f /html”xmlns : f=” h t tp : // java . sun . com/ j s f / core ”xmlns:p=” h t tp : // pr ime fa ce s . org / u i ”>

<h:head><meta cha r se t=”UTF−8”/>< t i t l e>Manter Produto</ t i t l e></h:head>

<h:body><h:form id=” formTable”>

<p :pane l header=”Manter Produto”><p:dataTable id=”dataTable ”value=”#{crtProduto . getAl lProdutos ( )} ”var=”produto ” se l ect ionMode=” s i n g l e ”s e l e c t i o n=”#{crtProduto . model}”rowKey=”#{produto . o id }”>< f : f a c e t name=”header ”>

Li s ta de Produtos</ f : f a c e t><p:column>

< f : f a c e t name=”header ” >Codigo</ f : f a c e t><h:outputText value=”#{produto . codigo }”/>

</p:column><p:column>

< f : f a c e t name=”header ” >Descr i c a o</ f : f a c e t><h:outputText value=”#{produto . d e s c r i c a o }”/>

</p:column>

89

Page 90: Desenvolvimento de Sistemas Cliente - Servidor utilizando

<p:column>< f : f a c e t name=”header ”>Valor Compra</ f : f a c e t><h:outputText value=”#{produto . valorCompra }”/>

</p:column><p:column>

< f : f a c e t name=”header ” >Valor Venda</ f : f a c e t><h:outputText value=”#{produto . valorVenda}”/>

</p:column><p:column>

< f : f a c e t name=”header ” >Fornecedor</ f : f a c e t><h:outputText value=”#{produto . f o rnecedo r }”/>

</p:column>< f : f a c e t name=” f o o t e r ”>

<p:commandButton value=” I n c l u i r ” id=” cb I n c l u i r ”update=” : f o rm: f o rmDeta i l ”i con=”ui−icon−e x t l i n k ”oncomplete=”PF( ’ dlg1 ’ ) . show ( ) ”

ac t i on=”#{crtProduto . createNewProduto}”/><p:commandButton value=”Al t e ra r ” id=” cbAlterar ”

update=” : f o rm: f o rmDeta i l ”i con=”ui−icon−e x t l i n k ”

oncomplete=”PF( ’ dlg1 ’ ) . show ( ) ”/>

<p:commandButton value=”Exc lu i r ” id=” cbExc lu i r ”i con=”ui−icon−e x t l i n k ”

oncomplete=”PF( ’ dlgRemove ’ ) . show ( ) ”/></ f : f a c e t>

</ p:dataTable></ p :pane l>

</h:form>

<p : d i a l o g width=”500” he ight=”50” id=” removeDialog ”modal=” true ”

header=”Confirma exc lu s a o do r e g i s t r o ?”widgetVar=”dlgRemove”><h:form id=”formRemove”>

<h:pane lGr id columns=”2”><h:commandButton ac t i on=”#{crtProduto . remove}”update=” : formTable” value=”OK” />

<h:commandButton immediate=” true ”update=” : formTable” value=”Cancel ” />

</ h :pane lGr id></h:form>

</ p : d i a l o g><h:form id=”form”>

<p : d i a l o g width=”500” he ight=”500” id=” d e t a i lD i a l o g ”modal=” true ”

header=”Detalhe do Produto” widgetVar=”dlg1 ”><h:pane lGr id id=” formDeta i l ” columns=”2”>

90

Page 91: Desenvolvimento de Sistemas Cliente - Servidor utilizando

<h:outputLabel name=” lb lCodigo ” value=”Codigo” /><p: inputText id=” txtCodigo ” l a b e l=” lb lCodigo ”

value=”#{crtProduto . model . codigo }” />

<h:outputLabel name=” lb lDe s c r i c a o ”value=”Descr i c a o ” />

<p: inputText id=” txtDesc r i cao ”l a b e l=” lb lDe s c r i c a o ”

value=”#{crtProduto . model . d e s c r i c a o }” />

<h:outputLabel name=” lblUnidade ”value=”Unidade” />

<p: inputText id=” txtUnidade ” l a b e l=” lblUnidade ”value=”#{crtProduto . model . unidade }” />

<h:outputLabel name=” lblValorCompra”value=”Valor Compra” />

<p: inputText id=”txtValorCompra”l a b e l=” lblValorCompra”

value=”#{crtProduto . model . valorCompra }” />

<h:outputLabel name=” lblValorVenda ”value=”Valor Venda” />

<p: inputText id=”txtValorVenda”l a b e l=” lblValorVenda ”

value=”#{crtProduto . model . valorVenda}” />

<h:outputLabel name=” lb lFo rnecedo r ”value=”Fornecedor ” />

<p: inputText id=” txtFornecedor ”l a b e l=” lb lFo rnecedo r ”

value=”#{crtProduto . model . f o rnecedo r }” />

<p:commandButton value=”OK”oncomplete=”PF( ’ dlg1 ’ ) . h ide ( ) ” id=”cbOK”act i on=”#{crtProduto . saveProduto }”update=” : formTable”/>

<p:commandButton value=”Cancelar ” id=” cbCancelar ”oncomplete=”PF( ’ dlg1 ’ ) . h ide ( ) ” update=” : formTable”/>

</ h :pane lGr id></ p : d i a l o g>

</h:form>

</h:body></html>

Realize o deploy da aplicacao e verifique se o cadastro de produto esta funcionandocorretamente conforme a Figura 3.62.

91

Page 92: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 3.62: Cadastro de Produtos

Agora podemos efetivamente implementar o cadastro pai-filho, para isso, vamos iniciarpelas classes entity no projeto SERVER dentro do pacote dao. Vamos criar duas classes:Pedido e ItemPedido repeitando o diagrama apresentado na Figura 3.61, conforme asListagens 3.36 e 3.37.

Listing 3.36: Classe entity dao.Pedido

package dao ;

import java . i o . S e r i a l i z a b l e ;import java . u t i l . ArrayList ;import java . u t i l . Date ;import java . u t i l . L i s t ;

import javax . p e r s i s t e n c e . CascadeType ;import javax . p e r s i s t e n c e . Column ;import javax . p e r s i s t e n c e . Ent ity ;import javax . p e r s i s t e n c e . GeneratedValue ;import javax . p e r s i s t e n c e . GenerationType ;import javax . p e r s i s t e n c e . Id ;import javax . p e r s i s t e n c e .ManyToOne ;import javax . p e r s i s t e n c e . NamedQueries ;import javax . p e r s i s t e n c e . NamedQuery ;import javax . p e r s i s t e n c e .OneToMany ;import javax . p e r s i s t e n c e . Temporal ;import javax . p e r s i s t e n c e . TemporalType ;

@NamedQueries({@NamedQuery (name=” queryAl lPedidos ” ,query=” S e l e c t p from Pedido p” )

})

@Entitypublic class Pedido implements S e r i a l i z a b l e {

@Id@GeneratedValue ( s t r a t e gy=GenerationType . IDENTITY)private int oid ;

92

Page 93: Desenvolvimento de Sistemas Cliente - Servidor utilizando

@Column( unique=true )private int numeroPedido ;@ManyToOne( cascade={CascadeType .MERGE, CascadeType .REFRESH})private Cl i en t e c l i e n t e ;@Temporal ( va lue=TemporalType .TIMESTAMP)private Date dataPedido ;@Column( length =1000)private St r ing observacoes ;

@OneToMany( cascade=CascadeType .ALL)private List<ItemPedido> c o l I t e n s =

new ArrayList<ItemPedido >() ;

public int getOid ( ) {return oid ;

}

public void setOid ( int oid ) {this . o id = oid ;

}

public int getNumeroPedido ( ) {return numeroPedido ;

}

public void setNumeroPedido ( int numeroPedido ) {this . numeroPedido = numeroPedido ;

}

public Cl i en t e g e tC l i en t e ( ) {return c l i e n t e ;

}

public void s e tC l i e n t e ( C l i en t e c l i e n t e ) {this . c l i e n t e = c l i e n t e ;

}

public Date getDataPedido ( ) {return dataPedido ;

}

public void setDataPedido (Date dataPedido ) {this . dataPedido = dataPedido ;

}

public St r ing getObservacoes ( ) {return observacoes ;

}

93

Page 94: Desenvolvimento de Sistemas Cliente - Servidor utilizando

public void setObservacoes ( S t r ing observacoes ) {this . observacoes = observacoes ;

}

public List<ItemPedido> ge tCo l I t en s ( ) {return c o l I t e n s ;

}

public void s e tCo l I t en s ( L i s t<ItemPedido> c o l I t e n s ) {this . c o l I t e n s = c o l I t e n s ;

}

}

Listing 3.37: Classe entity dao.ItemPedido

package dao ;

import javax . p e r s i s t e n c e . CascadeType ;import javax . p e r s i s t e n c e . Ent ity ;import javax . p e r s i s t e n c e . GeneratedValue ;import javax . p e r s i s t e n c e . Id ;import javax . p e r s i s t e n c e .ManyToOne ;

@Entitypublic class ItemPedido {

@Id@GeneratedValueprivate int oid ;@ManyToOne( cascade={CascadeType .MERGE,CascadeType .REFRESH})private Produto produto = new Produto ( ) ;private int quantidade ;private f loat va l o rUn i t a r i o ;private f loat percDesconto ;private f loat va l o rF ina l ;

@Overridepublic int hashCode ( ) {

f ina l int prime = 31 ;int r e s u l t = 1 ;r e s u l t = prime ∗ r e s u l t + oid ;return r e s u l t ;

}@Overridepublic boolean equa l s ( Object obj ) {

i f ( this == obj )return true ;

94

Page 95: Desenvolvimento de Sistemas Cliente - Servidor utilizando

i f ( obj == null )return fa l se ;

i f ( g e tC la s s ( ) != obj . g e tC la s s ( ) )return fa l se ;

ItemPedido other = ( ItemPedido ) obj ;i f ( o id != other . o id )

return fa l se ;return true ;

}public int getOid ( ) {

return oid ;}public void setOid ( int oid ) {

this . o id = oid ;}public Produto getProduto ( ) {

return produto ;}public void setProduto ( Produto produto ) {

this . produto = produto ;}public int getQuantidade ( ) {

return quantidade ;}public void setQuantidade ( int quantidade ) {

this . quantidade = quantidade ;}public f loat ge tVa lo rUn i ta r i o ( ) {

return va l o rUn i t a r i o ;}public void s e tVa lo rUn i ta r i o ( f loat va l o rUn i t a r i o ) {

this . v a l o rUn i t a r i o = va l o rUn i t a r i o ;}public f loat getPercDesconto ( ) {

return percDesconto ;}public void setPercDesconto ( f loat percDesconto ) {

this . percDesconto = percDesconto ;}public f loat getVa lorF ina l ( ) {

return va l o rF ina l ;}public void s e tVa lo rF ina l ( f loat va l o rF ina l ) {

this . v a l o rF ina l = va l o rF ina l ;}

}

O proximo passo e implementar a interface PedidoBeanLocal, no projeto SERVER no

95

Page 96: Desenvolvimento de Sistemas Cliente - Servidor utilizando

pacote EJB, com os metodos padroes de um CRUD, conforme a Listagem 3.38.

Listing 3.38: Interface PedidoBeanLocal

package e jb ;

import java . u t i l . L i s t ;import javax . e jb . Loca l ;import dao . Pedido ;

@Localpublic interface PedidoBeanLocal {

public void save ( Pedido pedido ) ;public List<Pedido> getAl lPed ido ( ) ;public void remove ( Pedido pedido ) ;public Pedido findByKey ( int oid ) ;

}

A classe EJB PedidoBean deve ser implementada no pacote EJB dentro do projetoServer, segundo o padrao das demais ja implementadas como mostra a Listagem 3.39.

Listing 3.39: Classe EJB PedidoBean

package e jb ;

import java . u t i l . L i s t ;

import javax . e jb . S t a t e l e s s ;import javax . p e r s i s t e n c e . EntityManager ;import javax . p e r s i s t e n c e . Pers i s t enceContext ;import javax . p e r s i s t e n c e . Query ;

import dao . Pedido ;import dao . Produto ;

@Sta t e l e s spublic class PedidoBean implements PedidoBeanLocal {

@Pers istenceContext ( unitName=” ds i 2012cont ext” )private EntityManager em ;

public PedidoBean ( ) {}

@Overridepublic void save ( Pedido pedido ) {

i f (em . f i nd ( Pedido . class ,pedido . getOid ( ) ) != null ){

em . merge ( pedido ) ;}else {

em . p e r s i s t ( pedido ) ;}

96

Page 97: Desenvolvimento de Sistemas Cliente - Servidor utilizando

}@Overridepublic List<Pedido> getAl lPed ido ( ) {

Query q =em . createNamedQuery ( ” queryAl lPedidos ” ) ;

L i s t<Pedido> co lPed idos = q . g e tRe su l tL i s t ( ) ;return co lPed idos ;

}@Overridepublic void remove ( Pedido pedido ) {

pedido = em . f i nd ( Pedido . class ,pedido . getOid ( ) ) ;i f ( pedido !=null ){

em . remove ( pedido ) ;}

}@Overridepublic Pedido findByKey ( int oid ) {

return ( Pedido )em . f i nd ( Pedido . class , o id ) ;}

}

Agora podemos partir para a implementacao da interface em JSF, mas antes vamospreparar as classes de controle e os conversores necessarios. A Listagem 3.40 apresenta ocodigo da classe control da tela de cadastro, observe que sao injetados tres EJBs, o Pedi-doBeanLocal que realizara as acoes basicas do cadastro. Os EJBs ProdutoBeanLocal e oClienteBeanLocal para alimentar as colecoes de clientes e produtos que serao apresentadasna interface atraves dos combobox. Alem do metodo createNewPedido que e chamado nobotao incluir da tela principal foi criado um novo metodo chamado createNewItemPedidoque e chamado na subtela para o cadastro do Item de Pedido, isso se replica para a acaode remover.

Listing 3.40: Classe control CrtPedido

package con t r o l ;

import java . u t i l . ArrayList ;import java . u t i l . L i s t ;

import javax . annotat ion . PostConstruct ;import javax . e jb .EJB;import javax . f a c e s . bean .ManagedBean ;import javax . f a c e s . bean . Sess ionScoped ;

import dao . C l i en t e ;import dao . ItemPedido ;import dao . Pedido ;import dao . Produto ;import e jb . Cl ienteBeanLocal ;import e jb . PedidoBeanLocal ;

97

Page 98: Desenvolvimento de Sistemas Cliente - Servidor utilizando

import e jb . ProdutoBeanLocal ;

@ManagedBean(name=” crtPedido ” )@SessionScopedpublic class CrtPedido {

@EJBprivate PedidoBeanLocal pedidoBeanLocal ;@EJBprivate ProdutoBeanLocal produtoBeanLocal ;@EJBprivate ClienteBeanLocal c l i en t eBeanLoca l ;

private List<Pedido> co lPed idos =new ArrayList<Pedido >() ;private List<Cl iente> c o lC l i e n t e s =new ArrayList<Cl iente >() ;private Pedido model = new Pedido ( ) ;private ItemPedido modelItem =new ItemPedido ( ) ;private List<Produto> co lProdutos =new ArrayList<Produto >() ;

@PostConstructpublic void loadData ( ){

c o lC l i e n t e s . addAll (c l i en t eBeanLoca l . g e tA l lC l i en t e ( ) ) ;

co lProdutos . addAll (produtoBeanLocal . getAl lProduto ( ) ) ;

}

public List<Produto> getColProdutos ( ) {return co lProdutos ;

}

public void setColProdutos (L i s t<Produto> co lProdutos ) {

this . co lProdutos = colProdutos ;}

public List<Cl iente> ge tCo lC l i en t e s ( ){return c o lC l i e n t e s ;

}

public void createNewPedido ( ){model = new Pedido ( ) ;

}

98

Page 99: Desenvolvimento de Sistemas Cliente - Servidor utilizando

public ItemPedido getModelItem ( ) {return modelItem ;

}

public void setModelItem (ItemPedido modelItem ) {

this . modelItem = modelItem ;}

public void createNewItemPedido ( ){modelItem = new ItemPedido ( ) ;model . g e tCo l I t en s ( ) . add (modelItem ) ;

}

public void removeItem (){i f (modelItem != null )

model . g e tCo l I t en s ( ) . remove (modelItem ) ;}

public void remove ( ){i f (model != null )

pedidoBeanLocal . remove (model ) ;}

public void savePedido ( ){pedidoBeanLocal . save (model ) ;

}

public List<Pedido> getAl lPed idos ( ){return pedidoBeanLocal . getAl lPed ido ( ) ;

}

public List<Pedido> getColPedidos ( ) {return co lPed idos ;

}

public void setCo lPed idos ( L i s t<Pedido> co lPed idos ) {this . co lPed idos = co lPed idos ;

}

public Pedido getModel ( ) {return model ;

}

public void setModel ( Pedido model ) {this . model = model ;

99

Page 100: Desenvolvimento de Sistemas Cliente - Servidor utilizando

}}

As proximas classes que devem ser implementadas sao: ClienteConverter conformea Listagem 3.41 e a classe ProdutoConverter conforme a Listagem 3.42. Como as duasclasses conversoras serao utilizadas na tela de Pedido e realizada a injecao de dependenciacom a classe de controle CrtPedido.

Listing 3.41: Classe conversor ClienteConverter

package con t r o l ;

import java . i o . S e r i a l i z a b l e ;

import javax . f a c e s . bean .ManagedBean ;import javax . f a c e s . bean . ManagedProperty ;import javax . f a c e s . bean . RequestScoped ;import javax . f a c e s . component . UIComponent ;import javax . f a c e s . context . FacesContext ;import javax . f a c e s . conver t . Converter ;

@ManagedBean(name=” c l i en t eConve r t e r ” )@RequestScopedpublic class Cl ienteConver ter implements Converter ,

S e r i a l i z a b l e {

@ManagedProperty( va lue = ”#{crtPedido }” )private CrtPedido crtPedido ;

@Overridepublic Object getAsObject ( FacesContext arg0 ,

UIComponent arg1 , S t r ing arg2 ) {int po s i t i o n = In t eg e r . pa r se In t ( arg2 ) ;return crtPedido . g e tCo lC l i en t e s ( ) . get ( p o s i t i o n ) ;

}

@Overridepublic St r ing getAsStr ing ( FacesContext arg0 ,UIComponent arg1 , Object arg2 ) {

returnSt r ing . valueOf ( crtPedido . g e tCo lC l i en t e s ( ) . indexOf ( arg2 ) ) ;

}

public void setCrtPedido ( CrtPedido crtPedido ) {this . crtPedido = crtPedido ;

}

}

Listing 3.42: Classe conversor ProdutoConverter

100

Page 101: Desenvolvimento de Sistemas Cliente - Servidor utilizando

package con t r o l ;

import java . i o . S e r i a l i z a b l e ;import javax . f a c e s . bean .ManagedBean ;import javax . f a c e s . bean . ManagedProperty ;import javax . f a c e s . bean . RequestScoped ;import javax . f a c e s . component . UIComponent ;import javax . f a c e s . context . FacesContext ;import javax . f a c e s . conver t . Converter ;

@ManagedBean(name=”produtoConverter ” )@RequestScopedpublic class ProdutoConverter implements Converter ,

S e r i a l i z a b l e {

@ManagedProperty( va lue = ”#{crtPedido }” )private CrtPedido crtPedido ;

@Overridepublic Object getAsObject ( FacesContext arg0 ,UIComponent arg1 , S t r ing arg2 ) {

int po s i t i o n = In t eg e r . pa r se In t ( arg2 ) ;return crtPedido . getColProdutos ( ) . get ( p o s i t i o n ) ;

}

@Overridepublic St r ing getAsStr ing ( FacesContext arg0 ,UIComponent arg1 , Object arg2 ) {

return St r ing . valueOf (crtPedido . getColProdutos ( ) . indexOf ( arg2 ) ) ;

}

public void setCrtPedido ( CrtPedido crtPedido ) {this . crtPedido = crtPedido ;

}}

Por ultimo vamos construir o codigo da interface FrmPedido conforme a Listagem3.43. Ele e um codigo bastante extenso porque cria diversos paineis para o controle docadastro pai e filho. Ao observar o codigo voce vera que existem duas dialogs, a primeira ea detailDialog q permite incluir o registro do pedido, ja a dialog detailItemDialog permitea inclusao de um Item de Pedido a colecao de itens dentro do pedido criado. Importanteobservar que a detailDialog possui dentro dela uma datatable para listar os itens dopedido.

Listing 3.43: Implementando o formulario na FrmPedido.xhml

< !DOCTYPE html><html xmlns=” h t tp : //www.w3 . org /1999/ xhtml”

101

Page 102: Desenvolvimento de Sistemas Cliente - Servidor utilizando

xmlns :u i=” h t tp : // java . sun . com/ j s f / f a c e l e t s ”xmlns:h=” h t tp : // java . sun . com/ j s f /html”xmlns : f=” h t tp : // java . sun . com/ j s f / core ”xmlns:p=” h t tp : // pr ime fa ce s . org / u i ”>

<h:head><meta cha r se t=”UTF−8”/>< t i t l e>Manter Pedido</ t i t l e>

</h:head>

<h:body><h:form id=” formTable”>

<p :pane l header=”Manter Pedido ”><p:dataTable id=”dataTable ”value=”#{crtPedido . getAl lPed idos ( )} ”var=”pedido ” se l ect ionMode=” s i n g l e ”s e l e c t i o n=”#{crtPedido . model}”rowKey=”#{pedido . o id }”>< f : f a c e t name=”header ”>Li s ta de Pedidos</ f : f a c e t><p:column>

< f : f a c e t name=”header ” >Numero</ f : f a c e t><h:outputText value=”#{pedido . numeroPedido}”/>

</p:column><p:column>

< f : f a c e t name=”header ” >Cl i en t e</ f : f a c e t><h:outputText value=”#{pedido . c l i e n t e . nome}”/>

</p:column><p:column>

< f : f a c e t name=”header ” >Cl i en t e</ f : f a c e t><h:outputText value=”#{pedido . dataPedido }”>

<f : convertDateTime pattern=”d/M/yyyy”/></h:outputText>

</p:column>< f : f a c e t name=” f o o t e r ”>

<p:commandButton value=” I n c l u i r ” id=” cb I n c l u i r ”update=” : f o rm: f o rmDeta i l ”i con=”ui−icon−e x t l i n k ” oncomplete=”PF( ’ dlg1 ’ ) . show ( ) ”ac t i on=”#{crtPedido . createNewPedido}”/>

<p:commandButton value=”Al t e ra r ” id=” cbAlterar ”update=” : f o rm: f o rmDeta i l ” i con=”ui−icon−e x t l i n k ”oncomplete=”PF( ’ dlg1 ’ ) . show ( ) ”/>

<p:commandButton value=”Exc lu i r ” id=” cbExc lu i r ”i con=”ui−icon−e x t l i n k ” oncomplete=”PF( ’ dlgRemove ’ ) . show ( ) ”/>

</ f : f a c e t></ p:dataTable>

</ p :pane l></h:form>

<p : d i a l o g width=”500” he ight=”50” id=” removeDialog ” modal=” true ”header=”Confirma exc lu s a o do r e g i s t r o ?” widgetVar=”dlgRemove”>

102

Page 103: Desenvolvimento de Sistemas Cliente - Servidor utilizando

<h:form id=”formRemove”><h:pane lGr id columns=”2”>

<h:commandButton ac t i on=”#{crtPedido . remove}”update=” : formTable” value=”OK” />

<h:commandButton immediate=” true ”update=” : formTable” value=”Cancel ” />

</ h :pane lGr id></h:form>

</ p : d i a l o g><h:form id=”form”>

<p : d i a l o g width=”700” he ight=”500” id=” d e t a i lD i a l o g ” modal=” true ”header=”Detalhe do Pedido” widgetVar=”dlg1 ”><h:pane lGr id id=” formDeta i l ” columns=”2”>

<h:outputLabel name=” lblNumero” value=”Numero” /><p: inputText id=”txtNumero” l a b e l=” lblNumero”value=”#{crtPedido . model . numeroPedido}” />

<h:outputLabel name=” l b lC l i e n t e ” value=”Cl i en t e ” /><p:selectOneMenu id=” cbCl i en t e ”

value=”#{crtPedido . model . c l i e n t e }”conver t e r=”#{c l i en t eConve r t e r }”>< f : s e l e c t I t em s value=”#{crtPedido . g e tCo lC l i en t e s ( )} ”

var=” item”itemLabel=”#{item . nome}” itemValue=”#{item}”/>

</p:selectOneMenu><h:outputText value=”Data: ” /><p : ca l enda r va lue=”#{crtPedido . model . dataPedido }”

id=” txtDataPedido ” showOn=”button ” /><h:outputText value=”Observa c o e s : ” /><p: inputTextarea

value=”#{crtPedido . model . observacoes }”rows=”5” c o l s=”30” maxlength=”1000”autoRes i ze=” f a l s e ”/>

<h:outputText value=” I t en s Pedido : ” /><p:dataTable id=”dataTablePedItem ” rows=”4”

value=”#{crtPedido . model . c o l I t e n s }”var=” itemPedido ” se l ect ionMode=” s i n g l e ”s e l e c t i o n=”#{crtPedido . modelItem }”rowKey=”#{itemPedido . o id }”>

< f : f a c e t name=”header ”>I t en s do Pedido</ f : f a c e t>

<p:column>< f : f a c e t name=”header ” >Numero</ f : f a c e t><h:outputText

value=”#{itemPedido . quantidade }”/></p:column><p:column>

< f : f a c e t name=”header ” >Produto</ f : f a c e t><h:outputText

103

Page 104: Desenvolvimento de Sistemas Cliente - Servidor utilizando

value=”#{itemPedido . produto . d e s c r i c a o }”/></p:column>< f : f a c e t name=” f o o t e r ”>

<p:commandButtonvalue=” I n c l u i r ” id=” cbInc lu i r I t em ”update=” : fo rmItem: fo rmItemDeta i l ”i con=”ui−icon−e x t l i n k ”oncomplete=”PF( ’ dlgItem ’ ) . show ( ) ”ac t i on=”#{crtPedido . createNewItemPedido }”/>

<p:commandButton value=”Al t e ra r ”id=” cbAlterarItem ”update=” : fo rmItem: fo rmItemDeta i l ”i con=”ui−icon−e x t l i n k ”oncomplete=”PF( ’ dlgItem ’ ) . show ( ) ”/>

<p:commandButton value=”Exc lu i r ”id=” cbExcluir Item ”icon=”ui−icon−e x t l i n k ”oncomplete=”PF( ’ dlgItemRemove ’ ) . show ( ) ”/>

</ f : f a c e t></ p:dataTable><p:commandButton value=”OK”

oncomplete=”PF( ’ dlg1 ’ ) . h ide ( ) ” id=”cbOK”act i on=”#{crtPedido . savePedido }”update=” : formTable”/>

<p:commandButton value=”Cancelar ” id=” cbCancelar ”oncomplete=”PF( ’ dlg1 ’ ) . h ide ( ) ” update=” : formTable”/>

</ h :pane lGr id></ p : d i a l o g></h:form>

<h:form id=” formItem”><p : d i a l o g width=”500” he ight=”300”

id=” deta i l I t emDia l og ” modal=” true ”header=”Detalhe do Item do Pedido ”widgetVar=”dlgItem ”><h:pane lGr id id=” formItemDeta i l ”

columns=”2”><h:outputLabel

name=” lb lProduto”value=”Produto” /><p:selectOneMenu id=”cbProduto ”

value=”#{crtPedido . modelItem . produto}”conver t e r=”#{produtoConverter }”>

< f : s e l e c t I t em svalue=”#{crtPedido . getColProdutos ( )} ”var=” item”itemLabel=”#{item . d e s c r i c a o }”itemValue=”#{item}”/>

104

Page 105: Desenvolvimento de Sistemas Cliente - Servidor utilizando

</p:selectOneMenu><h:outputLabel name=” lblQtd”

value=”Quantidade” /><h: inputText id=”txtQtd” l a b e l=” lblQtd”

value=”#{crtPedido . modelItem . quantidade }” /><h:outputLabel name=” lb lVa lo rUn i t ”

value=”Valor Un i t a r i o ” /><h: inputText id=” txtValorUnit ”

l a b e l=” lb lVa lo rUn i t ”value=”#{crtPedido . modelItem . va l o rUn i t a r i o }” />

<h:outputLabel name=” lb lPercDesc ”value=”Percentua l Desconto” />

<h: inputText id=” txtPercDesc ”l a b e l=” lb lPercDesc ”value=”#{crtPedido . modelItem . percDesconto }” />

<h:outputLabel name=” lb lVa l o rF ina l ”va lue=”Valor F ina l ” />

<h: inputText id=” txtVa lo rF ina l ”l a b e l=” lb lVa l o rF ina l ”va lue=”#{crtPedido . modelItem . va l o rF ina l }” />

<p:commandButton value=”OK”oncomplete=”PF( ’ dlgItem ’ ) . h ide ( ) ”id=”cbItemOK”update=” : f o rm: f o rmDeta i l ”/>

<p:commandButton value=”Cancelar ”id=” cbItemCancelar ”oncomplete=”PF( ’ dlgItem ’ ) . h ide ( ) ”async=” true ”update=” : f o rm: f o rmDeta i l ”/>

</ h :pane lGr id></ p : d i a l o g>

</h:form>

<p : d i a l o g width=”500” he ight=”50”id=” removeItemDialog ” modal=” true ”header=”Confirma exc lu s a o do Item?”widgetVar=”dlgItemRemove”><h:form id=”formItemRemove”>

<h:pane lGr id columns=”2”><p:commandButton

ac t i on=”#{crtPedido . removeItem }”update=” : f o rm: f o rmDeta i l ”va lue=”OK” />

<p:commandButtononcomplete=”PF( ’ dlgItemRemove ’ ) . h ide ( ) ”immediate=” true ”update=” : f o rm: f o rmDeta i l ”va lue=”Cancel ” />

</ h :pane lGr id>

105

Page 106: Desenvolvimento de Sistemas Cliente - Servidor utilizando

</h:form>

</ p : d i a l o g></h:body></html>

Apos concluir a implementacao, faca o deploy e acesse o FrmPedido.xhtml para veri-ficar o funcionamento.

3.5 Implementando a aplicacao cliente em Adobe Flex

4

Para iniciar a construcao da aplicacao cliente em Adobe Flex 4, devemos criar umnovo projeto do tipo Dynamic Web Project, sendo que esse projeto e necessario paraque a aplicacao Adobe Flex 4 e principalmente o servico de integracao com os EJBs,BlazeDS 4, esteja instalado dentro do Web Container do servidor JEE Glassfish. Paracriar este projeto, conforme ilustra a Figura 3.63, basta acessar o menu da IDE EclipseFile->New->Dynamic Web Project.

Figura 3.63: Criacao do projeto Dynamic Web Project

Na janela de dialogo do wizard de criacao do novo projeto Dynamic Web Project,como mostra a Figura 3.64, devera ser informado o Project Name onde sugere-se que onome termine com o sufixo WEB para facilitar a identificacao, alem de selecionar o Targetruntime para a colecao de bibliotecas do servidor Glassfish. E por fim, acionar o botaoFinish, para concluir a construcao do projeto.

106

Page 107: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 3.64: Criacao do projeto Dynamic Web Project - Configuracao do projeto

E possıvel observar pela Figura 3.65, que a estrutura de um projeto Dynamic WebProject e diferente do projeto EJB. Na pasta Java Resources, devem ser colocadas asclasses Java caso a aplicacao utilize uma tecnologia de desenvolvimento WEB Java comoJSP/Servlets/JSF. A pasta WebContent e o local onde todo o conteudo da aplicacao seramovido para que possa ser encontrado e executado pelo container WEB. Como nossoobjetivo e de construir uma aplicacao utilizando o Adobe Flex 4, necessitamos primeira-mente inserir neste projeto o servico de integracao BlazeDS 4, para entao adicionar aoprojeto as caracaterısticas de um projeto Adobe Flex 4 o que permitira compilar arquivosMXML.

107

Page 108: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 3.65: Estrutura de um projeto Dynamic Web Project

O BlazeDS 4 pode ser obtido atraves do site: http://sourceforge.net/adobe/blazeds/wiki/Home/,sendo que apos o download do pacote (blazeds-bin-4.0.1.21287.zip ou superior) contendoapenas os binarios ele deve ser descompactado. Como mostra a Figura 3.66, dentro destepacote havera um arquivo chamado blazeds.war que efetivamente e o conjunto de biblio-tecas necessarias para que o Adobe Flex 4 realize a comunicacao com a linguagem Java.Para importar este pacote para dentro de nosso projeto Dynamic Web Project, devemosrenomear o arquivo blazeds.war para blazeds.zip e em seguida descompactar seu conteudo,conforme a Figura 3.67.

Figura 3.66: Pacote BlazeDS Binary descompactado

108

Page 109: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 3.67: Pacote blazeds.war descompactado

O conteudo do arquivo blazeds.war sao duas pastas: META-INF e WEB-INF quecontem toda a biblioteca, como mostra a Figura 3.68. Essas pastas devem ser copiadase coladas diretamente dentro do projeto DSI2012WEB dentro do folder WebContent,sendo que sera apresentada uma mensagem solicitando a confirmacao da sobreescrita doconteudo que deve ser CONFIRMADA com opcao Yes to All , como ilustra a Figura 3.69.

Figura 3.68: Pacote META-INF e WEB-INF do BlazeDS

Figura 3.69: Copia dos diretorios META-INF e WEB-INF para o projeto WEB

Com isso nosso projeto recebe novas pastas que compoe as bibliotecas do BlazeDS,como apresenta a Figura 3.70, agora podemos adicionar ao projeto a caracterıstica de umprojeto Adobe Flex 4.

109

Page 110: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 3.70: Nova estrutura do projeto WEB

Para isso, basta clicar com o botao direito sobre o projet WEB, acionando as opcoes:Add/Change Project Type->Add Flex Project Type, como mostra a Figura 3.71.

110

Page 111: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 3.71: Adicionar caracterıstica de um projeto Adobe Flex 4

Na primeira tela do wizard apresentada, o IDE Eclipse ja apresenta a ultima versaodo SDK Adobe Flex 4 que foi configurada no capıtulo inicial deste guia, portanto bastaacionar a opcao Next, como apresenta a Figura 3.72.

Figura 3.72: Wizard - Adding Flex project type

O proximo passo do wizard e o mais importante, pois todas as principais caracterısticasdo projeto Adobe Flex 4 serao detalhadas, como ilustra a Figura 3.73. No grupo deparametros Server techonology deve ser selecionado Java como o Application server type,e a opcao Use remote object access service deve ser marcada para permitir o servico deintegracao BlazeDS possa ser selecionado como ponte de comunicacao entre o cliente e oservidor.

111

Page 112: Desenvolvimento de Sistemas Cliente - Servidor utilizando

No grupo de parametros server location, no campo Root folder, ser informado o cami-nho completo do projeto WEB ate o diretorio WebContent, no campo Root URL deve serinformado a URL pela qual a aplicacao Adobe Flex 4 sera acessada e por fim no campoContext root o nome relativo da aplicacao WEB, que consiste no final da Root URL,deve ser informado como caminho base do contexto da aplicacao. E obrigatorio acionaro botao Validate Configuration, para que os parametros acima informados possam servalidados. Por fim, no grupo de parametros Compiled Flex application location, o campooutput folder deve ter seu valor modificado para WebContent, desta maneira todos osarquivos compilados do Adobe Flex 4 em SWF serao copiados para o diretorio principalda aplicacao WEB. Para Finalizar basta acionar a opcao Finish.

Figura 3.73: Wizard - Configuracao do projeto Adobe Flex 4

Caso toda a configuracao esteja correta, a IDE Eclipse ira solicitar a troca da perspec-tiva para a do Adobe Flex 4 e o codigo em MXML principal da aplicacao sera apresentado.

Como o diretorio de contexto da aplicacao foi modificado, e apresentado um erro comomostra a Figura 3.74, pois o Adobe Flex 4 necessita regerar os arquivos HTML que servemde base para que o Flash Player carregue a aplicacao Flex 4. Para solucionar este erro,basta na lista de Problems, clicar sobre o item do erro com o botao direito e acionar aopcao Recreate HTML Templates.

112

Page 113: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 3.74: Processo de regerar os arquivos HTML da aplicacao Adobe Flex 4

3.5.1 Configuracao do BlazeDS para acesso aos EJBs

Para que a aplicacao Adobe Flex 4, atraves do BlazeDS 4, possa invocar nossos objetosEJB com a regra de negocio, necessitamos realizar a configuracao do BlazeDS. A tecnologiaAdobe Flex 4, realiza a comunicacao com o servidor atraves de diversas formas, sendo quea principal sao os Remote Objects. Atraves deste padrao, qualquer codigo Adobe Flex4 pode invocar metodos de classes em um servidor que podem ser escritos em diversaslinguagens como: Java, PHP ou C#.

Como o BlazeDS 4 nao da suporte nativo a invocacao de EJBs, precisamos incluirno projeto WEB uma nova biblioteca chamada flex-ejb-factory.jar, que pode ser obtidaatraves do site: http://www.adobe.com/cfusion/exchange/index.cfm?event=extensionDetail&extid=1089970

Como e possıvel observar na Figura 3.75, a biblioteca flex-ejb-factory.jar deve sercopiada para dentro da estrutura de diretorio: WebContent\WEB-INF\lib

113

Page 114: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 3.75: Inclusao da biblioteca flex-ejb-factory.jar

O proximo passo e alterar a configuracao do arquivo services-config.xml do BlazeDS4, para que ele reconheca a biblioteca que faz a integracao com os EJBs. Esse arquivoencontra-se na estrutura: WebContent\WEB-INF\flex, como mostra a Figura 3.76. Con-forme a Listagem 3.44, o TAG Factory deve ser inserido no xml.

114

Page 115: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 3.76: Configuracao do arquivo services-config.xml

Listing 3.44: Configuracao do services-config.xml

<?xml version=” 1 .0 ” encoding=”UTF−8”?><s e r v i c e s −con f i g>

<s e r v i c e s><s e r v i c e−i n c lude f i l e −path=” remoting−con f i g . xml” /><s e r v i c e−i n c lude f i l e −path=”proxy−con f i g . xml” /><s e r v i c e−i n c lude f i l e −path=”messaging−con f i g . xml” />

</ s e r v i c e s>

< f a c t o r i e s><f a c t o r y id=” ejb3 ”

c l a s s=”com . adobe . ac . e jb . EJB3Factory ”/></ f a c t o r i e s>

<s e c u r i t y><l og in−commandc l a s s=” f l e x . messaging . s e c u r i t y . TomcatLoginCommand”s e r v e r=”Tomcat”/>< !−− Uncomment the co r r e c t app s e r v e r

Agora para que o Adobe Flex 4, possa abstrair os EJBs como Remote Objects, devemosalterar o arquivo remoting-config.xml. E importante destacar que para cada EJB criadono servidor, devera ser criada uma nova estrutura utilizando o TAG destination dentrodo arquivo remoting-config.xml para que o remoting object do Flex 4 possa acessar a esteEJB.

A Figura 3.77, mostra como e a estrutura do destination, o atributo ID define por qualnome o codigo MXML do remoting object ira invocar o EJB. Dentro do TAG properties,deve ser informado o TAG factory indica que sera utilizada a biblioteca flex-ejb-factory.jarpara realizar a invocacao dos EJBs, o TAG source indica qual o caminho RMI paraa invocacao do EJB. Este caminho sera melhor detalhado apos o deploy da aplicacao.Importante destacar que o nome dos projetos, EJB e WEB influenciam na estruturadeste caminho. Por fim o tag scope define que o escopo para manutencao do estado

115

Page 116: Desenvolvimento de Sistemas Cliente - Servidor utilizando

do EJB, atributos internos do objeto, estara vinculado a sessao criada para este remoteobject.

Figura 3.77: Configuracao do arquivo remoting-config.xml

Listing 3.45: Configuracao do remoting-config.xml

<?xml version=” 1 .0 ” encoding=”UTF−8”?><s e r v i c e id=”remoting−s e r v i c e ”

c l a s s=” f l e x . messaging . s e r v i c e s . RemotingService ”>

<adapter s><adapter−d e f i n i t i o n id=” java−ob j ec t ”c l a s s=” f l e x . messaging . s e r v i c e s .remoting . adapter s . JavaAdapter” default=” true ”/>

</ adapter s>

<de s t i na t i on id=”ClienteBean ”><p r o p e r t i e s>

<f a c t o r y>e jb3</ f a c t o r y><source> j a v a : g l o b a l /DSI2012Server/DSI2012EJB/ClienteBean ! e jb . ClienteBeanRemote</ source><scope>s e s s i o n</ scope>

</ p r o p e r t i e s></ de s t i n a t i on>

Com isso, concluı-mos a configuracao do ambiente Flex 4 e podemos iniciar o desenvolvi-mento da aplicacao cliente.

3.5.2 Desenvolvimento da aplicacao cliente em Flex 4

Para iniciar o desenvolvimento do aplicativo Cliente, e importante criar uma estruturamınima de pacotes para organizar as classes do Flex 4. Conforme a Figura 3.78, dentrodo pacote src foram criados tres pacotes: comp (onde serao colocadas as classes MXMLdas interfaces do sistema, control (onde serao colocados os arquivos em ActionScript queserao a logica de controle das interfaces do sistema) e o pacote dao (onde serao colocadasas classes em ActionScript que servirao de espelho para as classes entity em Java).

116

Page 117: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 3.78: Estrutura de pacotes do projeto Flex 4

A primeira classe a ser criada sera a Cliente.as dentro do pacote dao, para isso cliquecom o botao direitor sobre o pacote dao e selecione a opcao: New->ActionScript Class.Esta classe, conforme a Figura 3.79, recebera o mesmo nome e atributos da classe entityescrita em Java, sendo que os tipos dos atributos precisam ser adaptados a biblioteca detipos da linguagem ActionScript. O principal objetivo da classe Cliente e de servir comoVO - Value Object, sendo que este tipo de objeto sera enviado pelo remote object ate o ladoserver da aplicacao. Ao chegar no servico BlazeDS, automaticamente os dados da classeCliente em ActionScript serao transferidos para a classe Cliente em Java possibilitandoassim a integracao das duas camadas da aplicacao de forma mais transparente. Para queessa classe funcione como meio de transporte dos dados, ela precisa receber a marcacao[RemoteClass(alias=”dao.Cliente”)] qeu indica que se trata de uma classe com ligacaoremota com outra classe escrita em outra linguagem do lado servidor. E importantedestacar que a classe em ActionScript deve possuir todos os atributos existentes na classeJava, e o nome dos atributos deve ser identico, uma simples alteracao de maiusculos ominusculos pode levar a aplicacao a ignorar o atributo durante a transmissao dos dados.

117

Page 118: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 3.79: Classe VO em ActionScript

Listing 3.46: Classe dao.Cliente em Action Script

package dao{

[ RemoteClass ( a l i a s=”dao . C l i en t e ” ) ][ Bindable ]

public class Cl i en t e{

public var o id : Number ;public var nome : S t r ing ;public var endereco : S t r ing ;public var t e l e f o n e : S t r ing ;public var idade : int ;public var dataNascimento : Date ;

public f unc t i on Cl i en t e ( ){}

}}

Agora estamos prontos para criar nossa primeira tela, para isso vamos utilizar o con-ceito de componentes do Flex 4. Clique com o botao direito sobre o pacote comp eselecione: New->MXML Componente, e conforme a Figura 3.80, sera apresentada a in-terface wizard para criacao de um novo componente. Modifique o nome da classe e nocampo Based on informe: spark.components.Panel com isso a interface que sera criadatera o aspecto de uma janela com barra de tıtulo e area central.

118

Page 119: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 3.80: Wizard para criar um Componente em Flex 4

Nossa interface para o CRUD Manter Cliente tera o aspecto igual a Figura 3.81. Paraobter essa interface, utilize o codigo contido na Listagem 3.51.

Figura 3.81: Interface principal para o caso de uso Manter Cliente

Listing 3.47: Codigo base do arquivo ClienteBnd.MXML

<?xml version=” 1 .0 ” encoding=”utf−8”?><s :Pane l xmlns : fx=” h t tp : //ns . adobe . com/mxml/2009”

xmlns:s=” l i b r a r y : //ns . adobe . com/ f l e x / spark ”xmlns:mx=” l i b r a r y : //ns . adobe . com/ f l e x /mx”width=”564” he ight=”300”

t i t l e=”Manter C l i en t e s ”>

119

Page 120: Desenvolvimento de Sistemas Cliente - Servidor utilizando

< f x :D e c l a r a t i o n s>< !−− Place non−v i s u a l e lements

( e . g . , s e r v i c e s , va l ue o b j e c t s ) here −−></ f x :D e c l a r a t i o n s><mx:VBox width=”100%” he ight=”100%”>

<s:DataGrid width=”100%” he ight=”90%” >

<s :co lumns><s :A r r ayL i s t>

<s:GridColumn dataFie ld=”nome”headerText=”Nome”/>

<s:GridColumn dataFie ld=” endereco ”headerText=”Endereco”/>

<s:GridColumn dataFie ld=” t e l e f o n e ”headerText=”Tele fone ”/>

<s:GridColumn dataFie ld=” idade ”headerText=” Idade ”/>

<s:GridColumndataFie ld=”dataNascimento”headerText=”Data Nascimento ”/>

</ s :A r r ayL i s t></ s:co lumns>

</ s:DataGrid><mx:HBox width=”100%” he ight=”10%”>

<s :Button id=”btbNovo” l a b e l=”Novo”/><s :Button id=” btbAlterar ” l a b e l=”Al t e ra r ”/><s :Button id=”btbSalvar ” l a b e l=” Sa lvar ”/><s :Button id=” btbExc lu i r ” l a b e l=” Exc lu i r ”/>

</mx:HBox></mx:VBox>

</ s :Pane l>

Agora que temos a interface base, devemos criar mais um componente para representara interface de formulario, que sera utilizada principalmente no processo de incluir e alterarnovos clientes. A Figura 3.82 ilustra o formulario que pode ser obtido com codigo daListagem 3.48.

120

Page 121: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 3.82: Interface de formulario para o caso de uso Manter Cliente

Listing 3.48: Codigo base do arquivo ClienteDetailBnd.MXML

<?xml version=” 1 .0 ” encoding=”utf−8”?><s :Pane l xmlns : fx=” h t tp : //ns . adobe . com/mxml/2009”

xmlns:s=” l i b r a r y : //ns . adobe . com/ f l e x / spark ”xmlns:mx=” l i b r a r y : //ns . adobe . com/ f l e x /mx”width=”470” he ight=”464” t i t l e=”Cl i en t e ”>

< f x :D e c l a r a t i o n s>< !−− Place non−v i s u a l e lements ( e . g . , s e r v i c e s , va l ue o b j

</ f x :D e c l a r a t i o n s><mx:VBox width=”100%” he ight=”100%”>

<s:Form width=”100%” he ight=”90%”><s:FormItem width=”441” l a b e l=”Nome:”>

<s :Text Input width=”286”/></ s:FormItem>

<s:FormItem width=”441” l a b e l=”Endere co : ”><s:TextArea width=”285”/>

</ s:FormItem>

<s:FormItem width=”442” l a b e l=” Te l e f on e : ”><s :Text Input width=”285”/>

</ s:FormItem>

<s:FormItem width=”442” l a b e l=” Idade : ”><s :Numer icStepper width=”66”/>

</ s:FormItem>

121

Page 122: Desenvolvimento de Sistemas Cliente - Servidor utilizando

<s:FormItem l a b e l=”Data de Nascimento: ”><mx:DateField />

</ s:FormItem>

</s:Form>

<mx:HBox width=”100%” he ight=”10%”><s :Button id=”btbOK” l a b e l=”OK”/><s :Button id=”btbCancelar ” l a b e l=”Cancelar ”/>

</mx:HBox></mx:VBox>

</ s :Pane l>

O proximo passo e a construcao dos arquivos em ActionScript que servirao de basepara a logica de controle das interfaces. Para isso crie dentro do pacote control doisActionScript File chamados ClienteCtr.as e ClienteDetailCtr.as. Entao podemos alterarnossas interfaces em MXML para realizar o link entre as interfaces e os dois arquivoscom a logica de controle, conforme a Listagem 3.49, na classe ClienteBnd.mxml logoapos a TAG Declarations insira a tag Script e informe no atributo source o caminhorelativo para o arquivo ClienteCtr.as. Conforme a Listagem 3.50, o mesmo deve ser feitopara a classe ClienteDetailBnd.xml, porem apontando o atributo source para o arquivoClienteDetailCtr.as.

Listing 3.49: Inclusao do TAG Script para link com o arquivo com a logica control da interface

<?xml version=” 1 .0 ” encoding=”utf−8”?><s :Pane l xmlns : fx=” h t tp : //ns . adobe . com/mxml/2009”

xmlns:s=” l i b r a r y : //ns . adobe . com/ f l e x / spark ”xmlns:mx=” l i b r a r y : //ns . adobe . com/ f l e x /mx”width=”564” he ight=”300” t i t l e=”Manter C l i en t e s ”>

< f x :D e c l a r a t i o n s>< !−− Place non−v i s u a l e lements ( e . g . , s e r v i c e s , va l ue o b j

</ f x :D e c l a r a t i o n s>

< f x : S c r i p t source=” . . / c on t r o l / Cl i enteCtr . as ”/>

<mx:VBox width=”100%” he ight=”100%”>

Listing 3.50: Inclusao do TAG Script para link com o arquivo com a logica control da interface

<?xml version=” 1 .0 ” encoding=”utf−8”?><s :Pane l xmlns : fx=” h t tp : //ns . adobe . com/mxml/2009”

xmlns:s=” l i b r a r y : //ns . adobe . com/ f l e x / spark ”xmlns:mx=” l i b r a r y : //ns . adobe . com/ f l e x /mx”width=”470” he ight=”464” t i t l e=”Cl i en t e ”>

< f x :D e c l a r a t i o n s>< !−− Place non−v i s u a l e lements ( e . g . , s e r v i c e s , va l ue o b j

</ f x :D e c l a r a t i o n s>

< f x : S c r i p t source=” . . / c on t r o l / C l i en t eDeta i lC t r . as ”/>

<mx:VBox width=”100%” he ight=”100%”>

122

Page 123: Desenvolvimento de Sistemas Cliente - Servidor utilizando

<s:Form width=”100%” he ight=”90%”>

Agora podemos criar o Remote Object, este componente da arquitetura Adobe Flex 4,como ja explicado, esse componente que ira realizar a conexao entre a aplicacao cliente como EJBs no servidor. Para isso sera necessario alterar o codigo da classe ClienteBnd.mxml,conforme a listagem 3.51. Dentro da TAG Declarations foi criado uma nova estruturade TAGs chamada RemoteObject, o atributo ID identifica a instancia do remote objecte define como ele sera chamado dentro do codigo em ActionScript, o atributo destina-tion deve ser informado com o nome do destination que foi criado dentro do arquivoremote-config.xml configurado com o caminho para o EJB. Dentro da estrutura de TAGRemoteObject, para cada metodo no EJB, deve ser criada uma TAG method que possuios atributos name que e o nome do metodo que existe no EJB e o result que e o nomeda funcao em actionScript que recebera o retorno da chamada do metodo EJB de formaassıncrona.

Listing 3.51: Criacao do remote object

<?xml version=” 1 .0 ” encoding=”utf−8”?><s :Pane l xmlns : fx=” h t tp : //ns . adobe . com/mxml/2009”

xmlns:s=” l i b r a r y : //ns . adobe . com/ f l e x / spark ”xmlns:mx=” l i b r a r y : //ns . adobe . com/ f l e x /mx”width=”564” he ight=”300” t i t l e=”Manter C l i en t e s ”>

< f x :D e c l a r a t i o n s><s:RemoteObject

id=” c l i en t eBean ”de s t i n a t i on=”ClienteBean ”showBusyCursor=” true ”>

<s:methodname=” ge tA l lC l i en t e ”r e s u l t=” re su l tHand l e r ( event ) ”/>

</ s:RemoteObject></ f x :D e c l a r a t i o n s>

< f x : S c r i p t source=” . . / c on t r o l / Cl i enteCtr . as ”/>

Precisamos agora alterar o arquivo ClienteCtr.as para incluir a funcao resultHandler,que ficara responsavel por receber os dados do servidor e atualizar a interface da aplicacaocliente. Observe, conforme a Listagem 3.52, que o codigo da funcao resultHandler iraapenas receber o resultado vindo do servidor EJB, e converte-lo para um ArrayCollection,objeto similar ao List da lingaguagem Java. Essa listagem e armazenada no atributocolClientes, criado no escopo de classe e marcado com o aspecto Bindable. Esse aspectoBindadle permite com que essa colecao sirva de fonte de dados para o DataGrid existentena interface ClienteBnd.mxml. Como pode ser observado na Listagem 3.53, o codigo daTAG DataGrid foi alterado para a inclusao de um novo atributo chamado dataProvidere o atributo colClientes foi passado entre chaves para indicar que existe um binding entreo atributo e o objeto DataGrid.

Listing 3.52: Codigo do arquivo ClienteCtr.as

123

Page 124: Desenvolvimento de Sistemas Cliente - Servidor utilizando

// Ac t i onScr i p t f i l eimport mx. c o l l e c t i o n s . Ar rayCo l l e c t i on ;import mx. rpc . events . ResultEvent ;

[ Bindable ]public var c o lC l i e n t e s : Ar rayCo l l e c t i on ;

protected f unc t i on r e su l tHand l e r ( event : ResultEvent ) : void{

c o lC l i e n t e s = event . r e s u l t as Ar rayCo l l e c t i on ;}

Listing 3.53: Inclusao do atributo dataProvider no DataGrid

< f x : S c r i p t source=” . . / c on t r o l / Cl i enteCtr . as ”/>

<mx:VBox width=”100%” he ight=”100%”><s:DataGrid width=”100%” he ight=”90%”dataProvider=”{ c o lC l i e n t e s }” >

<s :co lumns><s :A r r ayL i s t>

Para que a colClientes possa ser carregada, devemos realizar uma chamada remota dometodo getAllCliente configurado para o Remoting Object. Para isso vamos alterar nossaclasse ClienteCrt, para criar uma nova funcao chamada init, essa funcao tera como codigoa chamada do metodo remoto getAllClientes, conforme a Listagem 3.54.

Listing 3.54: Codigo do arquivo ClienteCtr.as

import f l a s h . events . Event ;

[ Bindable ]public var c o lC l i e n t e s : Ar rayCo l l e c t i on ;

protected f unc t i on i n i t ( event : Event ) : void{

c l i en t eBean . g e tA l lC l i en t e ( ) ;}

Agora devemos vincular a funcao init a o evento que e disparado no momento emque todos os componentes graficos de nossa interface MXML foram carregados, comoexemplifica a Listagem 3.55.

Listing 3.55: Vınculo do evento creationCompleted a funcao init

<?xml version=” 1 .0 ” encoding=”utf−8”?><s :Pane l xmlns : fx=” h t tp : //ns . adobe . com/mxml/2009”

xmlns:s=” l i b r a r y : //ns . adobe . com/ f l e x / spark ”xmlns:mx=” l i b r a r y : //ns . adobe . com/ f l e x /mx”width=”564” he ight=”300” t i t l e=”Manter C l i en t e s ”creat ionComplete=” i n i t ( event ) ”>

124

Page 125: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Por fim, vamos alterar o codigo do arquivo DSI2012WEB.mxml que foi criado no de-fault package da aplicacao Flex. Esse arquivo contem a TAG Application, que indica que,ele e o ponto de inıcio da aplicacao Flex que estamos desenvolvendo. O TAG Applicationcria a pagina basica que e carregada pelo Flash Player permitindo que as demais telas dosistema possam ser apresentadas no navegador. Para permitir um controle mais simplesdas subjanelas do sistema, vamos utilizar o componente ViewStack, ele permite criar umapilha de diversas subjanelas do sistema e atraves do componente LinkBar, sao criadoslinks para realizar a troca das interfaces visıveis, como e descrito na Listagem 3.56

Listing 3.56: Modificacao do codigo da classe MXML com a TAG Application

<?xml version=” 1 .0 ” encoding=”utf−8”?><s :App l i c a t i on xmlns : fx=” h t tp : //ns . adobe . com/mxml/2009”

xmlns:s=” l i b r a r y : //ns . adobe . com/ f l e x / spark ”xmlns:mx=” l i b r a r y : //ns . adobe . com/ f l e x /mx”

minWidth=”955” minHeight=”600” xmlns:comp=”comp .∗ ”>< f x :D e c l a r a t i o n s>

< !−− Place non−v i s u a l e lements ( e . g . , s e r v i c e s ,va l ue o b j e c t s ) here −−></ f x :D e c l a r a t i o n s><mx:VBox width=”100%” he ight=”100%”>

<mx:LinkBar dataProvider=”{ p i l h a t e l a s }”/>

<mx:ViewStack width=”100%” he ight=”100%”id=” p i l h a t e l a s ”>

<s :NavigatorContent width=”100%”he ight=”100%” l a b e l=”Cadast roCl i ente ”>

<comp:ClienteBnd/></ s:NavigatorContent>

</mx:ViewStack></mx:VBox>

</ s :App l i c a t i on>

3.5.3 Primeiro deploy da aplicacao

Para verificar se a aplicacao esta funcionando corretamente ate esse ponto, isso querdizer, se o grid ira carregar os dados que estao na tabela cliente do banco de dados,devemos realizar o processo de Deploy da aplicacao que nada mais e do que a instalacaoou publicacao do aplicativo dentro do servidor Glassfish. Primeiramente, verifique se oservico do banco de dados esta habilitado e se o servidor Glassfish esta carregado e como domınio inicializado. O proximo passo e criarmos um novo projeto em nossa workspaceno Eclipse, este projeto sera do tipo Enterprise Application Project. Para isso clique nomenu do Eclipse: FILE ->NEW ->Other. Na janela de wizard de novo projeto, conformeilustra a figura 3.83, selecione a opcao Java EE ->Enterprise Application Project e acionenext. Na primeira tela do wizard, informe o nome do projeto como DSI2012Server, comomostra a figura 3.84 e selecione o Target runtime como o servidor Glassfish, acione a opcaonext.

125

Page 126: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 3.83: Criando o projeto integrador para realizar o Deploy

126

Page 127: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 3.84: Criando o projeto integrador para realizar o Deploy

Na ultima tela deste wizard, como mostra a Figura 3.85, marque os dois projetosEJB e WEB e confirme no botao finish. Agora que o projeto de integracao esta pronto,podemos realizar o deploy, para isso como mostra a figura 3.86, clique com o botao direitosobre o novo projeto chamado DSI2012Server e selecione a opcao export ->EAR file.

127

Page 128: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 3.85: Criando o projeto integrador para realizar o Deploy

Figura 3.86: Exportando o projeto - DEPLOY

Para concluir o deploy, como mostra a Figura fig:AppFlex25, devemos informar o ca-minho completo ate a pasta autodeploy do servidor Glassfish, complementando o caminho

128

Page 129: Desenvolvimento de Sistemas Cliente - Servidor utilizando

com o nome do pacote que sera gerado com a extensao ear. E importante selecionar aopcao overwrite existing files, para que antigos arquivos ja exportados possam ser subs-tituıdos pelos novos atualizados. Para verificar se o deploy foi realizado com sucesso,verifique a mesma pasta onde o arquivo ear foi criado, como ilusta a Figura 3.88, caso oservidor Glassfish crie um arquivo com o mesmo nome do pacote ear mas com a terminacaoear deployed, isso significa que o pacote foi instalado no servidor com sucesso. Caso aterminacao tenha a palavra fail, verifique o log do servidor Glassfish para encontrar o errona aplicacao. Para realizar o teste da aplicacao abra sua ferramenta de gerenciamento dobanco de dados e execute as seguintes instrucoes SQL para criar um registro no banco dedados:

Figura 3.87: Exportando o projeto - DEPLOY

Figura 3.88: Exportando o projeto - DEPLOY

Listing 3.57: Instrucoes SQL para criar registros

use ds i2012goinsert into c l i e n t e (nome , endereco , t e l e f on e , idade ,

129

Page 130: Desenvolvimento de Sistemas Cliente - Servidor utilizando

dataNascimento ) values ( ’ Zezinho ’ , ’ rua l a l a l a 100 ’ ,’ 5555−1234 ’ , 22 , getdate ( ) )

go

Figura 3.89: Exportando o projeto - DEPLOY

O resultado esperado e apresentado na Figura 3.89, os dados inseridos no banco dedados devem ser apresentados na interface WEB quando a aplicacao e acessada.

IMPORTANTE:Este processo de deploy deve ser executado toda vez que a aplicacaosofrer alguma alteracao em seu codigo servidor ou Flex.

Como proximo passo, como descrito na Listagem 3.58, devemos alterar o codigo dosbotoes para inserir o evento de click que sera suportado pela funcao clickHandler que seracriada no arquivo ClienteCtr.as.

Listing 3.58: Inclusao evento de clique nos botoes de acao da interface

<mx:HBox width=”100%” he ight=”10%”><s :Button id=”btbNovo” l a b e l=”Novo”

name=”btbNovo” c l i c k=” c l i ckHand l e r ( event ) ”/><s :Button id=”btbAlterar ” l a b e l=”Al t e ra r ”

name=” btbAlterar ” c l i c k=” c l i ckHand l e r ( event ) ”/><s :Button id=”btbSalvar ” l a b e l=” Sa lvar ”

name=”btbSalvar ” c l i c k=” c l i ckHand l e r ( event ) ”/><s :Button id=”btbExc lu i r ” l a b e l=”Exc lu i r ”

name=” btbExc lu i r ” c l i c k=” c l i ckHand l e r ( event ) ”/></mx:HBox>

3.6 Implementando a aplicacao cliente em Swing

3.6.1 Configuracao do projeto Swing

O primeiro passo e a criacao de um novo projeto Java para desenvolver a interface emSwing conforme a figura 3.90. Voce deve clicar no menu File - new - Java Project, na tela

130

Page 131: Desenvolvimento de Sistemas Cliente - Servidor utilizando

de Wizard de criacao do projeto digite o nome do projeto e no item Use an executationJRE selecione a mesma versao do Java que foi utilizada para configurar o Glassfish.

Figura 3.90: Criacao do projeto Java Swing

131

Page 132: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 3.91: Wizard para criar um novo projeto Java

Como ilustra a figura 3.92, voce deve criar um package lib onde serao incorpora-das as bibliotecas JAR para o desenvolvimento do cliente em Swing. Va ate a pasta\glassfish4\glassfish\lib, copie o arquivo gf-client.jar e cole dentro do package lib comoesta na figura 3.93. Esse pacote de bibliotecas possibilita que o cliente Swing realize oprocesso de lookup dos EJBs, realizando chamadas remotas aos EJB para executar asacoes no lado servidor.

132

Page 133: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 3.92: Criacao do package para as bibliotecas

Figura 3.93: Arquivo gf-client.jar do Glassfish

Agora que a biblioteca foi incorporada ao projeto precisamos adiciona-la ao classpathde compilacao e de execucao do Java, para isso faca o que e mostrado na figura 3.94.Clique com o botao direito sobre a biblioteca, e selecione a opcoes Build Path ->Add toBuild Path.

Figura 3.94: Adicionando a lib gf-client ao classpath

133

Page 134: Desenvolvimento de Sistemas Cliente - Servidor utilizando

O proximo passo e adicionar a dependencia entre o projeto do cliente Swing e oprojeto EJB, isso se faz necessario por diversos motivos: o projeto Swing precisa trocardados com o servidor, para isso ele devera acessar os EJBs atraves de suas interfacesremotas, portanto ele precisa do codigo compilado destas interfaces; o projeto Swingtambem necessita trocar instancias com o servidor dos objetos Entity que estao no pacoteDAO do projeto EJB. Para isso voce deve realizar os passos que estao na figura 3.95, cliquesobre o projeto Swing com o botao direito do mouse e selecione Build Path ->ConfigureBuild Path.

Figura 3.95: Dependencia do projeto EJB

Conforme a tela de configuracao do projeto na figura 3.96, selecione a opcao no menua esquerda Java Build Path ->na aba Projects acione o botao Add..., na proxima janelaque sera apresentada selecione o projeto EJB e confirme no botao OK duas vezes.

Figura 3.96: Dependencia do projeto EJB

Antes de concluir as configuracoes, como mostra a figura 3.97, verifique se a versao dojava que esta sendo utilizada no projeto Swing, no projeto EJB e para executar o servidor

134

Page 135: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Glassfish sao as mesmas. Caso contrario, clique com o botao direito sobre a versao dojava utilizada no projeto que precisa ser corrigido, e selecione a opcao propriedades, naproxima tela, selecione a versao correta do java e confirme no botao OK, como mostra afigura 3.98.

Figura 3.97: Verificar a versao do JRE do projeto Swing com o projeto servidor

Figura 3.98: Verificar a versao do JRE do projeto Swing com o projeto servidor

135

Page 136: Desenvolvimento de Sistemas Cliente - Servidor utilizando

3.6.2 Iniciando a codificacao

Para iniciar a codificacao vamos criar um novo pacote chamado UTIL, neste pacotecomo mostra a figura 3.99 crie uma nova classe chamada ServerConnection com o codigosimilar ao da listagem 3.59.

Figura 3.99: Criacao do pacote UTIL

Esse codigo, classe ServerConnection, tem por objetivo criar um objeto Singleton deconexao com o servidor Glassfish. O design pattern singleton foi utilizado para garantirque apenas uma unica instancia do objeto ServerConnection seja mantida em memoria.Para codificar a conexao com seus EJBs, voce deve se basear no metodo em getCliente-BeanRemote, seguindo os passos:

• Crie um atributo no escopo de classe do mesmo tipo da interface remota de seuEJB. (private ClienteBeanRemote clienteBeanRemote;)

• Crie um metodo GETnomedasuainterfaceremota para manter o padrao, esse metododevera retornar a instancia do objeto armazenado no atributo criado no item ante-rior, mas antes de retornar verifique se a variavel tem o valor nulo. Caso sim, chameo metodo lookup passando o caminho logico para o EJB. Esse caminho pode serobtido de diversas formas, a mais simples e: faca o deploy da aplicacao servidor eentao procure no log do glassfish pelo nome do EJB, voce vai encontrar o caminho.

Listing 3.59: Exemplo classe ServerConnection

package u t i l ;

import java . u t i l . Hashtable ;import javax . naming . Context ;import javax . naming . I n i t i a lC on t ex t ;import javax . naming . NamingException ;

/∗∗ j a va : g l o b a l /PROJETO SERVER/PROJETO EJB/NomeBean ! e j b . NomeInterfaceRemota∗/

public class ServerConnect ion {// S i n g l e t o nprivate stat i c ServerConnect ion in s tance ;private I n i t i a lC on t ex t i c ;

136

Page 137: Desenvolvimento de Sistemas Cliente - Servidor utilizando

private ClienteBeanRemote cl ienteBeanRemote ;private ServerConnect ion ( ) {

try {i c = new I n i t i a lC on t ex t ( ) ;

} catch ( NamingException e ) {e . pr intStackTrace ( ) ;

}}public ClienteBeanRemote getClienteBeanRemote (){

i f ( cl ienteBeanRemote == null ){try {

cl ienteBeanRemote = ( ClienteBeanRemote )i c . lookup ( ” java : g l oba l /PROJETOSERVER/PROJETO EJB/NomeBean ! e jb . NomeInterfaceRemota ” ) ;

} catch ( NamingException e ) {e . pr intStackTrace ( ) ;

}}return cl ienteBeanRemote ;

}public stat i c ServerConnect ion get In s tance (){

i f ( i n s tance == null )i n s tance = new ServerConnect ion ( ) ;

return i n s tance ;}

}

O proximo passo da codificacao esta em criar um pacote com o nome de form e dentrodele uma nova classe chamada FrmCliente, como mostra a figura 3.100. Essa classe seraa tela inicial de nosso cadastro listando todos os registros dos clientes.

Figura 3.100: Tela principal de listagem

137

Page 138: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 3.101: Tela principal de listagem 2

O codigo da listagem 3.60 apresenta a base para a construcao da tela na figura 3.101,que e basicamente uma JFrame contendo dois paineis, no central existe uma JTable aindanao configurada e no painel do sul os botoes de acao.

Listing 3.60: Tela basica para listagem

package form ;

import java . awt . BorderLayout ;import javax . swing . JButton ;import javax . swing . JFrame ;import javax . swing . JPanel ;import javax . swing . JScrol lPane ;import javax . swing . JTable ;

public class FrmCliente extends JFrame{private JScrol lPane jpnTabela ;private JPanel jpnBotoes ;private JTable tabe l a ;private JButton btbNovo , btbAlterar , btbRemover ;

public FrmCliente ( ) {s e tDe fau l tCl oseOperat i on ( JFrame .EXIT ON CLOSE ) ;s e tT i t l e ( ”Manter C l i e n t e s ” ) ;c r i aPa ine lTabe l a ( ) ;c r i aPa ine lBotoes ( ) ;

s e t S i z e (500 , 300 ) ;s e tV i s i b l e ( true ) ;

}private void c r i aPa ine lTabe l a (){

tabe l a = new JTable ( ) ;jpnTabela = new JScrol lPane ( tabe l a ) ;add ( jpnTabela , BorderLayout .CENTER) ;

}private void c r i aPa ine lBotoes (){

btbNovo = new JButton ( ”Novo” ) ;btbAlterar = new JButton ( ” A l t e rar ” ) ;btbRemover = new JButton ( ”Remover” ) ;jpnBotoes = new JPanel ( ) ;jpnBotoes . add ( btbNovo ) ;jpnBotoes . add ( btbAlterar ) ;jpnBotoes . add ( btbRemover ) ;add ( jpnBotoes , BorderLayout .SOUTH) ;

}

public stat i c void main ( S t r i ng [ ] args ) {new FrmCliente ( ) ;

}}

O proximo passo e criar uma classe que ira guiar a forma como os dados serao apre-sentados na tabela, para isso deve ser criado um pacote no projeto com o nome model, edentro dele uma classe com o nome de ModeloTabCliente como mostra a figura 3.102. Alistagem 3.61 mostra a classe ModeloTabCliente, inicialmente ela deve extender a classeabstrata AbstractTableModel, o que obrigara a implementacao dos metodos basicos ge-

138

Page 139: Desenvolvimento de Sistemas Cliente - Servidor utilizando

tRowCount, getColumnCount e getValueAt. Na primeira linha da classe vamos criar umavariavel do tipo arraylist para armazenar a colecao de clientes que sera apresentada natabela, no metodo getRowCount sera retornado o numero de objetos dentro da colecaoe no metodo getColumnCount sera retornado um numero fixo de colunas existentes. Ometodo getValueAt e responsavel por trasformar a colecao de objetos em informacoespara cada celula. Por fim o metodo atualiza sera chamado sempre que os dados da tabelaprecisarem ser atualizados.

Figura 3.102: Classe de modelo para a tabela

Listing 3.61: Modelo da tabela cliente

package model ;

import java . t ex t . SimpleDateFormat ;import java . u t i l . ArrayLi st ;import java . u t i l . L i s t ;import javax . swing . tab l e . AbstractTableModel ;import dao . Cl i en te ;

public class ModeloTabCliente extends AbstractTableModel{

private List<Cl iente> colDados = new ArrayList<Cl iente >() ;private SimpleDateFormat sd f = new SimpleDateFormat( ”dd/MM/yyyy” ) ;private St r i ng [ ] t i t u l o s = {”Codigo” , ”Nome” , ”Data Nascimento” } ;

@Overridepublic St r i ng getColumnName ( int column) {

return t i t u l o s [ column ] ;}

public void a tua l i z a ( L i st<Cl iente> colDados ){this . colDados = colDados ;f i reTableDataChanged ( ) ;

}

@Overridepublic int getRowCount ( ) {

return colDados . s i z e ( ) ;}

@Overridepublic int getColumnCount ( ) {

return 3 ;}

@Overridepublic Object getValueAt( int l inha , int coluna ) {

Object va l or = null ;C l i en t e umCliente = colDados . get ( l i nha ) ;

139

Page 140: Desenvolvimento de Sistemas Cliente - Servidor utilizando

switch ( coluna ) {case 0 :

va l or = umCliente . getCodigo ( ) ;break ;case 1 :

va l or = umCliente . getNome ( ) ;break ;case 2 :

va l or = sd f . format ( umCliente . getDataNascimento ( ) ) ;break ;

default :break ;

}return va l or ;

}}

Agora podemos alterar o codigo da classe FrmCliente para criar uma instancia daclasse ModeloTabCliente, associar a instancia do modelo a JTable e principalmente criarum metodo atualizaTabela que ira atraves da classe ServerConnection realizar o lookuppara chamar o EJB do lado servidor e executar a consulta que ira retornar a lista declientes, conforme as linhas grifadas na listagem 3.62. Execute a class FrmCliente e casoexistam linhas na tabela do banco de dados, eles serao apresentado na JTable.

Listing 3.62: Instanciando o modelo na janela de listagem

public class FrmCliente extends JFrame{private JScrol lPane jpnTabela ;private JPanel jpnBotoes ;private JTable tabe l a ;private JButton btbNovo , btbAlterar , btbRemover ;private ModeloTabCliente modelTab ;

public FrmCliente ( ) {s e tDe fau l tCl oseOperat i on ( JFrame .EXIT ON CLOSE ) ;s e tT i t l e ( ”Manter C l i e n t e s ” ) ;c r i aPa ine lTabe l a ( ) ;c r i aPa ine lBotoes ( ) ;s e t S i z e (500 , 300 ) ;s e tV i s i b l e ( true ) ;

}private void c r i aPa ine lTabe l a (){

modelTab = new ModeloTabCliente ( ) ;a tua l i zaTabe l a ( ) ;t abe l a = new JTable (modelTab ) ;jpnTabela = new JScrol lPane ( tabe l a ) ;add ( jpnTabela , BorderLayout .CENTER) ;

}public void atua l i zaTabe l a (){

modelTab . a t u a l i z a ( ServerConnect ion . ge t In s tance ( ) . getCl ienteBeanRemote ( ) . g e tA l lC l i e n t e s ( ) ) ;}

Com a tela principal pronta, podemos iniciar o desenvolvimento do formulario queira permitir incluir e alterar os dados de um Cliente. Para isso e importante utilizar umgerenciador de layout para organizar os campos no formato de formulario. Como ilustraa figura 3.103, copie e cole o pacote LayoutAuxiliares.jar para dentro da pasta lib, cliquecom o botao direito sobre o pacote ->Build Path ->Add to BuildPath.

140

Page 141: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 3.103: Pacote LayoutAuxiliar.jar

A listagem 3.64 apresenta o codigo do formulario para incluir ou alterar o registro deum cliente. Observe que a classe define um formulario, foi destacada as linhas do metodosupdateForm e updateModel que sao responsaveis por atualizar os campos da tela com osdados do objeto model e o segundo faz o processo contrario de atualizar o objeto modelcom os dados dos campos da tela, respectivamente. Observe que no metodo construtorda classe recebe uma instancia da classe cliente, armazena a instancia do objeto em umavariavel model e entao chama o metodo updateForm para atualizar a tela com os dados.

Listing 3.63: Codigo do formulario

package form ;import java . awt . Dimension ;import java . t ex t . ParseExcept ion ;import java . t ex t . SimpleDateFormat ;

import javax . swing . ButtonGroup ;import javax . swing . JButton ;import javax . swing . JDialog ;import javax . swing . JFormattedTextField ;import javax . swing . JFrame ;import javax . swing . JLabel ;import javax . swing . JPanel ;import javax . swing . JRadioButton ;import javax . swing . JTextFie ld ;import javax . swing . JToolBar ;import javax . swing . t ex t . MaskFormatter ;

import ui . u t i l . l ayou t s . ParagraphLayout ;import dao . Cl i en te ;

public class FrmCl ienteDetai l extends JDialog {private JToolBar jpnBotoes ;private JPanel jpnCentro ;private JButton btbOK, btbCancelar ;private JLabel lb lCodigo , lblNome , lblNascimento , l b l S exo ;private JTextFie ld txtCodigo , txtNome ;private JRadioButton jrbMascButton , jrbFemButton ;private ButtonGroup group = new ButtonGroup ( ) ;private JFormattedTextField txtNascimento ;private Cl i en te model ;

141

Page 142: Desenvolvimento de Sistemas Cliente - Servidor utilizando

private SimpleDateFormat sd f = new SimpleDateFormat( ”dd/MM/yyyy” ) ;

public void updateForm(){txtCodigo . setText (model . getCodigo ( ) ) ;txtNome . setText (model . getNome ( ) ) ;jrbMascButton . s e t S e l e c t e d (model . i sS exo ( ) ) ;i f (model . getDataNascimento( ) != null )

txtNascimento . setText ( sd f . format (model . getDataNascimento ( ) ) ) ;}public void updateModel (){

model . setNome( txtNome . getText ( ) ) ;model . setCodigo ( txtCodigo . getText ( ) ) ;model . setSexo ( jrbMascButton . i s S e l e c t e d ( ) ) ;try {

model . setDataNascimento ( sd f . parse ( txtNascimento . getText ( ) ) ) ;} catch ( ParseExcept ion e ) {}

}public FrmCl ienteDetai l ( C l i en te c l i e n t e ) {

setModal ( true ) ;s e tDe fau l tCl oseOperat i on ( JFrame .DISPOSE ON CLOSE) ;s e t S i z e (450 , 210 ) ;s e tT i t l e ( ”Manter Cl i en te ” ) ;i n i tLayout ( ) ;model = c l i e n t e ;updateForm ( ) ;s e tV i s i b l e ( true ) ;

}private void i n i tLayout (){

doJpnCentro ( ) ;doJpnBotoes ( ) ;

}private void doJpnCentro (){

jpnCentro = new JPanel (new ParagraphLayout ( ) ) ;lb lCodigo = new JLabel ( ”Codigo” ) ;txtCodigo = new JTextFie ld ( 6 ) ;

lblNome = new JLabel ( ”Nome” ) ;txtNome = new JTextFie ld ( 20 ) ;

l b l S exo = new JLabel ( ”Sexo” ) ;jrbFemButton = new JRadioButton ( ”Feminino” ) ;jrbMascButton = new JRadioButton ( ”Mascul ino” ) ;group . add ( jrbFemButton ) ;group . add ( jrbMascButton ) ;

MaskFormatter mascData = null ;try {

mascData = new MaskFormatter ( ”##/##/####” ) ;} catch ( ParseExcept ion e ) {

e . pr intStackTrace ( ) ;}lb lNasc imento = new JLabel ( ”Data Nascimento : ” ) ;txtNascimento = new JFormattedTextField (mascData ) ;txtNascimento . s e tP r e f e r r e dS i z e (new Dimension ( 12 0 , 22 ) ) ;

jpnCentro . add ( lb lCodigo , ParagraphLayout .NEWPARAGRAPH) ;jpnCentro . add ( txtCodigo ) ;

jpnCentro . add ( lblNome , ParagraphLayout .NEWPARAGRAPH) ;jpnCentro . add ( txtNome ) ;

jpnCentro . add ( lb lSexo , ParagraphLayout .NEWPARAGRAPH) ;jpnCentro . add ( jrbMascButton ) ;jpnCentro . add ( jrbFemButton ) ;

jpnCentro . add ( lblNascimento , ParagraphLayout .NEWPARAGRAPH) ;jpnCentro . add ( txtNascimento ) ;

add ( ”Center” , jpnCentro ) ;}private void doJpnBotoes (){

jpnBotoes = new JToolBar ( ) ;jpnBotoes . s e tF l oa tab l e ( fa l se ) ;btbOK = new JButton ( ”OK” ) ;btbOK. setName( ”btbOK” ) ;btbCancelar = new JButton ( ”Cancelar ” ) ;btbCancelar . setName( ” btbCancelar ” ) ;jpnBotoes . add (btbOK) ;jpnBotoes . add ( btbCancelar ) ;add ( ”South” , jpnBotoes ) ;

}}

A listagem 3.104 apresenta a criacao do pacote control no projeto swing para contero codigo que ira controlar os eventos da tela de formulario. Para isso clique com o botaodireito sobre a pasta SRC ->clique em new ->package e informe o nome control.

142

Page 143: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Figura 3.104: Criando o pacote control

Listing 3.64: Codigo do formulario

import java . awt . Component ;import java . awt . event . ActionEvent ;import java . awt . event . Act i onL i s t ener ;import java . u t i l . L i s t ;import model . ModeloTabCliente ;import u t i l . ServerConnect ion ;import dao . Cl i en te ;import form . FrmCliente ;

public class CrtFrmCliente implements Act i onL i s t ener{

private FrmCliente frame ;private ModeloTabCliente tableModel ;public CrtFrmCliente ( FrmCliente frmCl iente , ModeloTabCliente tableModel ) {

this . frame = frmCl iente ;this . tableModel = tableModel ;

}@Overridepublic void act ionPer formed ( ActionEvent e ) {

Component comp = (Component ) e . getSource ( ) ;// aqu i v a i a l o g i c a dos b o t o e s

}

private void updateJTable (){List<Cl iente> l i s t a C l i e n t e s = ServerConnect ion . ge t In s tance ( ) .

getCl ienteBeanRemote ( ) . g e tA l lC l i e n t e s ( ) ;tableModel . a t u a l i z a ( l i s t a C l i e n t e s ) ;

}}

143

Page 144: Desenvolvimento de Sistemas Cliente - Servidor utilizando

Referencias Bibliograficas

144