sexta-feira, 17 de setembro de 2010

Tutorial Java + Flex utilizando o EasyEclipse - Dia dois

Eu tinha planejado já pesquisar e estudar a conexão com bancos de dados no Java antes de fazer a integração com o Flex, porém ao buscar uma forma que fazer tanto backend quanto frontend para o projeto eu não fiquei satisfeito com as opções que encontrei. A primeira opção era, claro, fazer um programa desktop em Java mesmo, mas a programação desktop em Java, pelo menos no Windows, é horrível e o resultado ficou muito abaixo das minhas expectativas. A outra solução possível seria continuar a programar em JSP como fizemos no tutorial passado, mas o código fica muito bagunçado. Web Service é uma ótima opção e vou estudar mais tarde mas, no momento, sairia muito de nosso escopo.

Por isso, antes de conectar com o banco de dados, vamos já fazer a integração do Flex com o Java.




Continuando com a configuração que tínhamos no fim de nosso primeiro tutorial, agora precisamos configurar o Flex para que possamos programar tanto em Java quanto em Flex usando a mesma IDE.

Para iniciar, baixe e instale a versão 3 do Flex Builder, pode ser a versão trial. Eu tentei utilizar a versão 4 mas o normal não funcionou e o plugin está bugado. Eu desisti do plugin depois de quase 3 horas instalando.

Vá até a pasta de instalação do Flex (Padrão é em "C:\Arquivos de programas\Adobe\Flex Builder 3") e copie a pasta sdk para dentro da pasta do EasyEclipse (Padrão é em "C:\Arquivos de programas\EasyEclipse Expert Java 1.3.1.1") depois entre na pasta Plugins no Flex e copie todo seu conteúdo para a pasta Plugins do EasyEclipse (Se for perguntado se deseja sobrescrever os arquivos responda sim).

Antes de terminarmos de configurar a nossa IDE, baixe o BlazeDS binário no site da Adobe.






Sim é esse de apenas 4Mb que precisamos mesmo. Descompacte o arquivo baixado, crie uma pasta chamada Biblioteca na mesma pasta da instalação do EasyEclipse (Ou algum outro local que você prefira) e copie o arquivo blazeds.war para lá.

Agora abra o EasyEclipse, vá em Window -> Preference. Procure por Flex e confira se o caminho dos SDKs não apresenta nenhum sinal de aviso:




Agora já podemos montar nosso projeto integrado de Java e Flex. Vá novamente em File -> New -> Project. Você perceberá agora que agora temos a opção de criar projetos Flex:



Escolha Flex Project e clique em Next.

Em Project Name coloque o nome do seu projeto, em Project Location mantenha o default (Como default ele cria uma pasta com o nome do seu projeto no workspace da IDE), Application type deixe em Web Application, em Server Technology escolha J2EE, deixe as opções Use remote object access device e LiveCycle Data Services marcados assim como a opção Create a combined Java/Flex project using WTP também marcado e o campo Java source folder com o seu valor padrão que é "src":


Na próxima página, em Target Runtime você indica o servidor em que rodará a aplicação. Se já existir a opção Tomcat 6.0 que usamos no tutorial passado pule esse trecho da configuração do servidor, senão, clique em New.

Configurando o Servidor

Na janela que se abrirá, em Select the server type, escolha Apache -> Tomcat v6.0 Server. Em Server runtime, se já existir a opção Apache Tomcat v6.0, escolha-o, senão, clique em Installed Runtimes...



Na nova janela clique em Add:



Agora escolha Apache -> Apache Tomcat v6.0:


Clique em Next, e na próxima página, preencha o campo Name com o nome do servidor, por exemplo, Apache Tomcat v6.0, em Tomcat installation directory, indique a pasta onde está instalado o tomcat (Normalmente em "C:\Arquivos de programas\Apache Software Foundation\Tomcat 6.0"), e em JRE escolha  "Workbench default JRE":



Clique em Finish. e cliquem em OK até voltarmos à pagina escrita Define a New Server:


Em Server Runtime escolha a configuração que acabamos de fazer e clique em Next e na próxima página não precisa mexer em nada e clique em Finish.

Voltando ao Projeto

Voltando novamente ao nosso projeto (Lembrando que só precisamos configurar o servidor no máximo uma vez):


Em Target runtime escolha o nosso servidor da aplicação (Normalmente o Apache tomcat v6.0). Context root estará preenchido com o nome de nossa aplicação, deixe como está. Em Content folder existe uma armadilha de me custou um domingo de dor de cabeça. Essa opção indica o nome do diretório que irá armazenar os arquivos de configuração do aplicativo, porém, mais na frente ao tentar fazer uma comunicação entre o Java e o Flex podemos ter o seguinte retorno de erro:

[RPC Fault faultString="Falha no envio" 
faultCode="Client.Error.MessageSend" 
faultDetail="Channel.Connect.Failed error NetConnection.Call.Failed: HTTP: 
Status 404: url: 'http://localhost:8080/WebContent/messagebroker/amf'"] 


Isso acontece porque o servidor amf é levantado em "http://localhost:8080/NomeDoProjeto/messagebroker/amf" que no nosso caso será http://localhost:8080/FlexJava/messagebroker/amf' e o BlazeDS irá procurar o servidor em http://localhost:8080/WebContent/messagebroker/amf'. Colocando o Content Folder com nome igual de nosso Context Root esse problema será evitado.


Você se lembra do nosso arquivo blazeds.war? Pois então, em Flex WAR file, indique o caminho para esse arquivo. Os outros campos pode ser deixado em seu valor padrão:



 Clique em Next. Na próxima página deixe os valores como o padrão e clique em Finish:




Ao ser perguntado se deseja mudar a perspectiva para o Flex, pode responder sim para que ela seja configurada.



Nosso projeto está pronto e podemos começar a programar. Podemos testar nosso servidor clicando com o botão direito no projeto e escolhendo a opção Runs As - Run on Server:




Na janela que irá aparecer, escolha um servidor disponível e clique em Finish:




Se não existir nenhum servidor configurado ou aparecer alguma mensagem de erro:




Marque a opção Manually define a new server, em Server's host name mantenha localhost, em Select server type escolha Apache -> Tomcat v6.0 server, em Server runtime escolha Apache tomcat v6.0 e clique em Finish




Se tudo der certo aparecerá essa página na IDE:






Apesar de ser também um aviso de erro (Ele avisa que não encontrou nenhuma página para o endereço solicitado) ele indica que nosso servidor e nosso projeto básico está OK até aqui.


Se você expandir a pasta bin-debug verá que já existe uma página com o nome do seu projeto e a extensão html:




O que precisamos fazer agora é avisar ao Tomcat que essa página deve ser carregada quando alguém tentar acessar o endereço de nossa aplicação. Para isso abra a pasta com o nome do seu projeto, dentro dele existirá mais duas pastas, META-INF e WEB-INF, abra WEB-INF e dentro dela existirá outras pastas inportantes pra nós e o arquivo web.xml. Abra esse arquivo xml:




Clique nos sinais de + para expandir o caminho web-app -> welcome-file-list:




Essa é a lista de páginas que o servidor irá procurar e, se encontrado, carregar quando alguém acessar o endereço de nosso projeto. Por padrão ele vem com os arquivos index.html e index.htm, que obviamente não existem em nosso projeto. Clique com o botão direito na tag welcome-file-list e escolha a opção Add Child ->welcome-file:




Altere a segunda coluna com o nome do arquivo html da pasta bin-debug:




Salve o projeto indo em File ->Save All ou com o atalho Ctrl + Shift + S:




Rode novamente o projeto e dessa vez não teremos mais o erro de página não encontrada, pois o Tomcat procurou o arquivo que configuramos e o carregou:






Meio sem graça por enquanto, mas antes de mexer nessa página, vamos preparar as funções que iremos usar. Depois desse ponto, a programação em nosso projeto segue um esquema simples:
  1. Criar a classe no Java com as suas funções;
  2. Informar ao BlazeDS quais classes serão enviadas ao Flex;
  3. Avisar no Flex quais classes e funções poderão ser utilizados;
  4. Tratar as respostas e usar as funções cadastradas;
  5. Criar e configurar a tela para o usuário.
Simples assim.


Vamos começar criando uma classe java em nosso projeto. Para isso clique com o botão direito na pasta principal de nosso projeto e escolhas as opções New -Other...:




Na janela que irá se abrir, escolha a opção Java -> Class e clique em Next:






Na próxima página Source folder indica a pasta onde será criado o arquivo com o código fonte. Deixe o padrão. O campo Package da classe, é a organização de seus códigos no projeto, por exemplo, posso querer que exista um package subheaven que por sua vez engloba os packages entidades para classes que carregam os dados de um banco de dados, conexao para classes que tratam da comunicação com os bancos de dados, carregamento das classes em entidades e manutenção dos mesmo como inserir, alterar e excluir, um package servicos para armazenar as classes que conterão funções que serão acessadas diretamente pelo usuário e tals. Depois informe o nome da sua classe em Name, deixe o campo Modifiers como public, em Superclass você indica uma classe da qual a sua vai herdar, em nosso caso deixe a classe padrão que é java.lang.Object e o resto dos campos deixe o padrão:




Clique em Finish


Agora vamos modificar a classe e adicionar o seguinte código:



import java.util.*;


public class Utils {
public String olaMundo() {
  return "Testando a comunicação entre o Flex e o Java";

}
public String Cumprimento(String Nome) {
Date Data = new Date();
int Hora = Data.getHours();

if (Hora < 12) {
return "Bom dia " + Nome + ".";
}
else if (Hora < 18) {
return "Boa tarde " + Nome + ".";
}
else if (Hora < 23) {
return "Boa noite " + Nome + ".";
}
else {
return "Olá " + Nome + ". Não sei que hora é agora. =/";
}
}
}


Note que adicionamos uma import, para indicar que vamos usar uma função da classe Calendar da package java.utils e mais duas funções, olaMundo e Cumprimento. A primeira apenas retorna um texto simples e já a segunda recebe um nome, verifica a hora atual e o cumprimenta de acordo com o horário.

Com isso terminamos o passo 1. Agora vamos avisar ao BlazeDS para disponibilizar essa classe criada, e consequentemente suas duas funções para o Flex. Para isso, vá à pasta WEB-INF -> flex e abra o arquivo remoting-config.xml:





Expanda a tag service, depois clique com o botão direito nela e escolha Add Child -> New Element...:




Coloque o nome como destination:




Uma nova tag foi adicionada em service. agora clique com o botão direito na tag destination e escolha Add Attribute -> New Attribute:




Preencha o campo Name com id e o campo Value com o nome que será disponibilizado para a sua classe (Pode ser qualquer nome, mas esse valor é importante na hora de avisar ao Flex quais classes e funções ele poderá usar):




Agora clique novamente com o botão direito em destination e agora escolha Add Child ->New Element...:




Coloque o nome de properties:




Clique com o botão direito em properties e escolha Add Child -> New Element e agora coloque o nome de source:




E finalmente, clique com o botão direito nessa nova tag, a source, e escolha New Child -> #PCDATA:




Preencha o campo a direita que foi liberada para alteração e coloque a package e o nome da classe que será disponibilizada:


Essa deve ser a estrutura final do arquivo remoting-config.xml se aberto em um editor de texto:




<?xml version="1.0" encoding="UTF-8"?> 

<service id="remoting-service" class="flex.messaging.services.RemotingService">
    <adapters>         

          <adapter-definition id="java-object" class="flex.messaging.services.remoting.adapters.JavaAdapter" default="true"/>
    </adapters>
          <default-channels>         

          <channel ref="my-amf"/>     
          </default-channels>
    <destination id="Servico.Utils">      

          <properties>       
                <source>
                      subheaven.servicos.Utils
                </source>      
          </properties>     
    </destination> 
</service>



Com isso terminado o Passo 2.


Agora procure o arquivo com o nome do seu projeto e extensão mxml e abra-o:




Vamos agora avisar qual classe e quais funções o Flex poderá requisitar ao Java. Adicione o código a seguir:




<mx:RemoteObject id="utils" 
            destination="Servico.Utils" 
            showBusyCursor="true">
            
<mx:method name="olaMundo" 
      fault="FaultHandler(event);" 
      result="olaMundoResult(event);"/>
      
<mx:method name="Cumprimento" 
      fault="FaultHandler(event);" 
      result="CumprimentoResult(event);"/>
</mx:RemoteObject>


A tag RemoteObject indica ao Flex, qualquer objeto remoto que poderá ser usado por ele. Essa tag precisa ter um atributo id que será o nome identificador desse objeto dentro do Flex e um atributo destination que deve ser exatamente o mesmo id do destination que configuramos no arquivo remoting-config. O atributo showBusyCursor indica se será mostrado um cursor de espera enquanto o objeto estiver em uso.

Dentro dessa tag adicionamos uma tag Method, que indica quais funções será usadas e como tratar suas respostas. Seus atributos obrigatórios são name, que deve ser obrigatoriamente igual ao nome da função no Java, o atributo fault, que indica qual função no Flex será chamado caso ocorra algum erro e o atributo result que indica a função que será chamada para tratar a resposta. Nome que as funções de tratamento de fault e result recebem um parâmetro event que será passado automaticamente pelo BlazeDS que contém detalhes da resposta.









Com isso terminamos o passo 3. Se você tentar salvar o projeto agora, ele irá tentar fazer o rebuild e indicará 4 erros. eles são por causa das funções de resposta do objeto remoto declarado anteriormente e que ainda não foram criados no Flex.


Para isso, vamos criar um arquivo de ActionScript no Flex clicando com o botão direito em nosso projeto e escolhendo a opção New - Other:






Na nova janela escolha Flex Builder - ActionScript File e clique em Next:




Na próxima página, preencha o campo Filename com o nome que você deseja para o arquivo com a extensão as:






Clique em Finish e um arquivo de script em branco será mostrado:




Agora vamos importar as classes Flex que iremos usar adicionando:



import flash.events.MouseEvent;
import mx.controls.Alert;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;

Depois vamos adicionar 5 funções. A primeira para tratar qualquer erro de comunicação:


public function FaultHandler(event: FaultEvent): void {
Alert.show(event.fault.toString(), "Erro");
}

Nela chamamos um alerta indicando o conteúdo do erro.

Agora criamos uma função para tratar a resposta da função remota olaMundo():


public function olaMundoResult(event: ResultEvent): void {
Alert.show(event.result.toString(), "Sucesso");
}




Ela novamente chama o alerta e mostramos o conteúdo da resposta.


A próxima função é pra tratar a resposta e Cumprimento. Ela é idêntica à anterior:



public function CumprimentoResult(event: ResultEvent): void {
  Alert.show(event.result.toString(), "Sucesso");
}

Agora criamos duas funções que serão chamadas por dois botões na tela e que irão executar as funções remotas:


public function btnOlaMundoClick(event: MouseEvent): void {
utils.olaMundo();
}

public function btnCumprimentoClick(event: MouseEvent): void {
utils.Cumprimento(tiNome.text);
}





Note que usei a id declarada em RemoteObject seguida do nome do método. A função remota Cumprimento recebe um parâmetro Nome e indicamos entre os parênteses que esse parâmetro será recebido da propriedade text de um componente na tela chamado itNome que iremos criar no ultimo passo. Veja como ficou nosso arquivo de ActionScript:







Finalmente, volte para o arquivo mxml e indique que ele deverá usar esse arquivo de action script com o comando:


<mx:Script source="FlexJava.as"/>


O código até agora do mxml deverá ficar assim:



Agora só falta criarmos a tela que será usada pelo usuário para executar isso tudo. Nesse mesmo arquivo mxml, clique na aba Design:


No canto baixo-esquerda fica a lista de componentes que podem ser usados para montar sua página. Procure por Panel e arraste-o para a área central. Depois disso modifique a posição e o tamanho ao seu gosto e, nas propriedades que ficam a direita, modifique o Title de nosso Panel:





Agora volte à lista de componentes e arraste um Button para dentro de nosso Panel e preencha as propriedades ID com btnOlaMundo, a propriedade Label com um texto qualquer que aparecerá no botão e onClick com a função "btnOlaMundoClick(event);":




Agora adicione um componente TextInput e preencha a propriedade ID com tiNome (O componente que a IDE estava pedindo):


 


E por fim adicione outro Button:




Salve tudo e agora podemos testar nossa aplicação.




Desse ponto em diante, para adicionar funções basta seguir o ciclo:


1 - Criar a função;
2 - Se for um classe nova, informar no arquivo remoting-config.xml;
3 - Se for apenas uma nova função em classes já configuradas, adicionar uma tag mx:method no arquivo NomeDoProjeto.mxml dentro da tag RemoteObject apropriada, se for uma nova classe adicionar uma tag mx:RemoteObject e, nela, adicionar o link pra função;
4 - Usar.


Agora sim, temos um ambiente de programação preparado para a conexão com o banco de dados. Até a próxima.

Nenhum comentário:

Postar um comentário