Olá pessoal!
Depois de alguns dias sem postar nada no blog, vou atender ao pedido de alguns colegas que fizeram um curso de Scrum a uns dias atrás e postar algo no blog sobre como começar um projeto com Java e Flex, como faço para “instalar” o BlazeDS e fazer minha primeira comunicação.
Para quem está iniciando no desenvolvimento Flex com Java como back-end e está optando por trabalhar com Remote Objects precisa trabalhar com algo que faça a comunicação entre Flex e Java.
Existem diversas opções hoje no mercado, e a própria Adobe disponibiliza dois produtos para isso. O objetivo desse tutorial é exemplificar o uso do BlazeDS para essa comunicação.
O BlazeDS é uma ferramenta open-source, e hoje é amplamente utilizada para a comunicação Java – Flex. Tem como objetivo prover ao desenvolvedor Flex uma forma de se comunicar com seu back-end através de Remote Objects ou comunicação Real-Time através de Messages.
Vale lembrar que o BlazeDS pode ser utilizado para comunicações de aplicações desenvolvidas em Flex para Web (Flash Player) ou para Desktop (AIR).
Mas como iniciar? Primeiramente, devemos fazer o download (clique aqui para o download) através do site oficial do BlazeDS.
O download que estamos fazendo é a versão binária, contendo um arquivo .WAR que contém os arquivos .xml e os .jars necessários para a sua utilização. Também é possível fazer o download do código-fonte do BlazeDS clicando aqui.
Após o download e sua descompactação, também é necessário descompactar o arquivo blazeds.war. Para isso, você poderá utilizar um descompactador como o WinRAR por exemplo. Fazendo isso, obteremos a seguinte estrutura:
O conteúdo da pasta META-INF será desconsiderado. Levaremos em consideração apenas o conteúdo da pasta WEB-INF conforme seguinte apresentação:
A pasta classes e src serão desconsideradas nesse tutorial também.
Dentro da pasta flex, temos os arquivos XMLs necessários para configuração em nosso projeto que será criado no Java, e na pasta lib, temos as bibliotecas java (*.jar) que deverão ser incorporados em nosso projeto. E o arquivo web.xml contém as informações necessárias para a configuração do servlet em nosso projeto.
Nesse artigo, o software utilizado para criação e desenvolvimento do projeto Java é Eclipse Galileu junto com o WebTools. Você pode tranquilamente adaptar esse tutorial para qualquer IDE que você utilize em seu dia-a-dia.
Para iniciar um projeto, eu escolhi a opção File -> New -> Web -> Dynamic Web Project, conforme abaixo:
E depois configurei o projeto da seguinte maneira:
Bom, depois de configurar o projeto, iremos criar um Bean para serializarmos algumas informações que serão enviadas para o Flex. A idéia é bastante simples, irei criar um model para uma simples agenda de contato.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
package br.com.horochovec.model; import java.io.Serializable; /** * Modelo para agenda de contato * @author Stefan Horochovec */ public class Contato implements Serializable { /** * */ private static final long serialVersionUID = 1L; private String nome; private String email; public String getNome() { return nome; } public void setNome(String nome) { this.nome = nome; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } } |
E em seguida, criarei um serviço que irá adicionar em um ArrayList os contatos que serão enviados do Flex para o Java.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
package br.com.horochovec.service; import java.util.ArrayList; import br.com.horochovec.model.Contato; /** * Serviço para manutenção dos contatos * @author Stefan Horochovec */ public class ContatoService { private static ArrayList listContato = new ArrayList(); /** * Adiciona um contato a lista * @param contato */ public void addContato(Contato contato) { listContato.add(contato); } /** * Retorna a lista de contatos * @return */ public ArrayList getListContato() { return listContato; } } |
Após isso, já temos uma simples aplicação pronta para trabalhar com o Flex, basta apenas configurar os arquivos .XML para que o BlazeDS possa funcionar.
O primeiro arquivo que iremos configurar, é o arquivo web.xml que fica dentro da pasta WebContent/WEB-INF/. Para essa configuração, iremos adicionar o conteúdo do arquivo web.xml que veio dentro do arquivo blazeds.war que foi previamente descompactado. O resultado será:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
<?xml version="1.0" encoding="UTF-8"?> <web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <display-name>FlexDuck</display-name> <welcome-file-list> <welcome-file>FlexDuck.html</welcome-file> </welcome-file-list> <!-- Http Flex Session attribute and binding listener support --> <listener> <listener-class>flex.messaging.HttpFlexSession</listener-class> </listener> <!-- MessageBroker Servlet --> <servlet> <servlet-name>MessageBrokerServlet</servlet-name> <servlet-class>flex.messaging.MessageBrokerServlet</servlet-class> <init-param> <param-name>services.configuration.file</param-name> <param-value>/WEB-INF/flex/services-config.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>MessageBrokerServlet</servlet-name> <url-pattern>/messagebroker/*</url-pattern> </servlet-mapping> </web-app> |
Feito isso, iremos adicionar dentro da pasta WebContent a pasta flex que foi previamente descompactada do arquivo blazeds.war, e também todo o conteúdo da pasta lib para dentro do diretório WebContent/WEB-INF/lib , obtendo o seguinte resultado:
Feito isso, iremos configurar o único arquivo .xml do BlazeDS para que esse exemplo funcione. O arquivo WEB-INF/flex/remoting-config.xml. Iremos adicionar uma configuração para informar ao BlazeDS sobre o serviço ContatoService que foi criado anteriormente, conforme abaixo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<?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="ContatoService"> <properties> <source>br.com.horochovec.service.ContatoService</source> </properties> </destination> </service> |
Após essa última configuração, podemos exportar o nosso projeto para um servidor web. Nesse caso, utilizaremos o Tomcat 6.x. Neste artigo não entrarei em detalhes de sua instalação e configuração.
Bom, as configurações no projeto Java já foram finalizadas, e considerando que o deploy da aplicação dentro do Tomcat já foi realizado, a partir deste momento iremos trabalhar diretamente com o Flex.
Neste artigo irei demonstrar a comunicação utilizando o Flash Builder e a versão do Flex 4. Você pode fazer o download da versão 4.0 do Flash Builder e do Flex 4 SDK aqui.
Após instalado e iniciado o Flash Builder, iremos criar um projeto no seguinte molde:
As configurações feitas na segunda tela de configuração são bastante importantes. Fazendo elas da forma correta, você estará apto a iniciar o projeto sem fazer novas configurações.
Na primeira linha, em Root Folder, foi apontado o diretório de deploy da minha aplicação dentro do meu servidor de aplicação.
Na segunda linha, em Root URL, foi apontado o caminho da URL para abertura da aplicação em meu navegador de internet.
Na terceira linha, em ContextRoot, apontamos o nome da nossa aplicação.
Na quarta e ultima linha, em Output folder, apontamos o diretório de onde deve ser exportados os arquivos quando compilados. Para esse tutorial, foi apontado diretamente o diretório de minha aplicação dentro do meu servidor Tomcat.
Como resultado, o Flash Builder irá criar e disponibilizar no workspace um projeto da seguinte forma:
É muito importante fazer a conferência de uma configuração gerada automaticamente pelo Flash Builder em cima dos parametros informados na segunda etapa da criação do projeto. No menu ‘Project’ vá na opção ‘Properties’ e confira as propriedades de acordo com a imagem abaixo:
Após conferir essas informações, podemos iniciar o desenvolvimento do projeto no Flex.
Primeiramente, iremos criar o bean que será enviado para o Java e vice-versa. Esse bean será um espelho do bean criado no Java, conforme abaixo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
package br.com.horochovec.model { [RemoteClass(alias="br.com.horochovec.model.Contato")] [Bindable] public class Contato { public var nome : String; public var email : String; public function Contato() { } } } |
Em seguida, irei criar uma tela no Flash Builder que contenha dois campos text input para preencher as informações do nome e email do contato, e também um grid para conter a lista dos contatos que serão adicionados no Java e retornarão ao Flex através do BlazeDS.
Segue sua implementação
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx"> <fx:Declarations> <!-- Place non-visual elements (e.g., services, value objects) here --> </fx:Declarations> <s:Panel width="400" height="137" title="Cadastro" left="10" top="10"> <s:Button x="55" label="Cadastrar" bottom="10" id="btnCadastro"/> <s:Label x="10" y="16" text="Nome:"/> <s:Label x="13" y="50" text="Email:"/> <s:TextInput x="56" y="10" width="332" id="nome"/> <s:TextInput x="56" y="44" width="332" id="email"/> </s:Panel> <s:Panel x="12" y="166" width="400" height="227" title="Pesquisa" left="10"> <mx:DataGrid x="10" y="10" bottom="30" left="5" right="5" top="5" id="grid" dataProvider="{this.listContato}"> <mx:columns> <mx:DataGridColumn headerText="Nome" dataField="nome"/> <mx:DataGridColumn headerText="Email" dataField="email"/> </mx:columns> </mx:DataGrid> <s:Button x="-1" y="163" label="Listar todos" left="5" bottom="5"/> </s:Panel> </s:Application> |
Após a construção da tela, iremos criar o serviço remoto que será responsável pela comunicação com o Java. Conforme trecho abaixo, criaremos um RemoteObject e dois métodos para serem executados pela aplicação. Definiremos também os métodos que devem ser disparados quando ocorrerem os retornos, tanto de sucesso quanto de falha na comunicação.
1 2 3 4 5 6 7 8 9 10 11 12 |
<fx:Declarations> <s:RemoteObject id="remoteObject" destination="ContatoService" fault="onFault(event);"> <s:method name="addContato" result="onResultAddContatoHandler(event);" fault="onFault(event);" /> <s:method name="getListContato" result="onResultGetListContatoHandler(event);" fault="onFault(event);" /> </s:RemoteObject> </fx:Declarations> |
Feito isso, faremos a implementação dos métodos a cima informados para resultados do RemoteObject.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
<fx:Script> <![CDATA[ import br.com.horochovec.model.Contato; import mx.collections.ArrayList; import mx.controls.Alert; import mx.rpc.events.FaultEvent; import mx.rpc.events.ResultEvent; [Bindable] public var contato : Contato = new Contato(); [Bindable] public var listContato : ArrayList = new ArrayList(); /** * Metodo para falhas na comunicação */ protected function onFault(event:FaultEvent) : void { Alert.show('Erro'); } /** * Funcao para retorno de cadastro do Contato */ protected function onResultAddContatoHandler(event:ResultEvent) : void { Alert.show('Adicionado'); } /** * Funcao para retorno da lista de contatos */ protected function onResultGetListContatoHandler(event:ResultEvent) : void { this.listContato = event.result as ArrayList; } ]]> </fx:Script> |
Agora, iremos implementar no botão do painel de cadastro e ao botão no painel de listagem de informações, o evento de click para que seja enviado ao java o bean para cadastro e solicitado ao java a lista de contatos.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<s:Panel width="400" height="137" title="Cadastro" left="10" top="10"> <s:Button x="55" label="Cadastrar" bottom="10" id="btnCadastro" click="btnCadastroClickHandler(event)"/> <s:Label x="10" y="16" text="Nome:"/> <s:Label x="13" y="50" text="Email:"/> <s:TextInput x="56" y="10" width="332" id="nome"/> <s:TextInput x="56" y="44" width="332" id="email"/> </s:Panel> <s:Panel x="12" y="166" width="400" height="227" title="Pesquisa" left="10"> <mx:DataGrid x="10" y="10" bottom="30" left="5" right="5" top="5" id="grid" dataProvider="{this.listContato}"> <mx:columns> <mx:DataGridColumn headerText="Nome" dataField="nome"/> <mx:DataGridColumn headerText="Email" dataField="email"/> </mx:columns> </mx:DataGrid> <s:Button x="-1" y="163" label="Listar todos" left="5" bottom="5" id="btnListar" click="btnListarClickHandler(event)"/> </s:Panel> |
Com os eventos de click de cada botão implementados, falta apenas fazer a implementação de seus métodos. Para isso vamos adicionar ao bloco fx:script o seguinte código:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
/** * Evento de click do botão de cadastro */ protected function btnCadastroClickHandler(event:MouseEvent):void { this.remoteObject.addContato(this.contato); } /** * Evento de click do botão de pesquisa */ protected function btnListarClickHandler(event:MouseEvent):void { this.remoteObject.getListContato(); } |
Para finalizar o código, irei adicionar o Binding entre os dois TextInput e o bean que será serializado para o Java:
1 2 |
<fx:Binding source="nome.text" destination="contato.nome" twoWay="true"/> <fx:Binding source="email.text" destination="contato.email" twoWay="true"/> |
Feito isso, pronto, nossa aplicação de teste está pronta para o uso final, como resultado, obtemos:
A implementação completa do Flex será:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
<?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx"> <fx:Script> <![CDATA[ import br.com.horochovec.model.Contato; import mx.collections.ArrayCollection; import mx.controls.Alert; import mx.rpc.events.FaultEvent; import mx.rpc.events.ResultEvent; [Bindable] public var contato : Contato = new Contato(); [Bindable] public var listContato : ArrayCollection = new ArrayCollection(); /** * Metodo para falhas na comunicação */ protected function onFault(event:FaultEvent) : void { Alert.show('Erro'); } /** * Funcao para retorno de cadastro do Contato */ protected function onResultAddContatoHandler(event:ResultEvent) : void { Alert.show('Adicionado'); } /** * Funcao para retorno da lista de contatos */ protected function onResultGetListContatoHandler(event:ResultEvent) : void { this.listContato = event.result as ArrayCollection; } /** * Evento de click do botão de cadastro */ protected function btnCadastroClickHandler(event:MouseEvent):void { this.remoteObject.addContato(this.contato); } /** * Evento de click do botão de pesquisa */ protected function btnListarClickHandler(event:MouseEvent):void { this.remoteObject.getListContato(); } ]]> </fx:Script> <fx:Binding source="nome.text" destination="contato.nome" twoWay="true"/> <fx:Binding source="email.text" destination="contato.email" twoWay="true"/> <fx:Declarations> <s:RemoteObject id="remoteObject" destination="ContatoService" fault="onFault(event);"> <s:method name="addContato" result="onResultAddContatoHandler(event);" fault="onFault(event);" /> <s:method name="getListContato" result="onResultGetListContatoHandler(event);" fault="onFault(event);" /> </s:RemoteObject> </fx:Declarations> <s:Panel width="400" height="137" title="Cadastro" left="10" top="10"> <s:Button x="55" label="Cadastrar" bottom="10" id="btnCadastro" click="btnCadastroClickHandler(event)"/> <s:Label x="10" y="16" text="Nome:"/> <s:Label x="13" y="50" text="Email:"/> <s:TextInput x="56" y="10" width="332" id="nome"/> <s:TextInput x="56" y="44" width="332" id="email"/> </s:Panel> <s:Panel x="12" y="166" width="400" height="227" title="Pesquisa" left="10"> <mx:DataGrid x="10" y="10" bottom="30" left="5" right="5" top="5" id="grid" dataProvider="{this.listContato}"> <mx:columns> <mx:DataGridColumn headerText="Nome" dataField="nome"/> <mx:DataGridColumn headerText="Email" dataField="email"/> </mx:columns> </mx:DataGrid> <s:Button x="-1" y="163" label="Listar todos" left="5" bottom="5" id="btnListar" click="btnListarClickHandler(event)"/> </s:Panel> </s:Application> |
Você pode fazer o download do projeto aqui.
Obrigado e um abraço a todos!




















