Post sobre como criar um projeto no novo Adobe Flash Builder 4, de um projeto Flex 4 com BlazeDS 4 e um exemplo de comunicação via Remoting, segue…
Para este post serão necessários os items:
- Adobe Flash Builder 4 plugin
- BlazeDS 4 ( versão Beta utilizada: Nightly Builds > 4.0.0.14910 )
Criando projeto:
Parar criar o projeto iremos precisar do BlazeDS.war previamente, da versão indicada neste post, então, na perspectiva Flash, iremos criar nosso projeto:
Temos 2 alternativas para criar um novo projeto Flex:
- Através do menu: File > New > Flex Project
- Clicar com botão direito, na área em branco do Package Explorer, no popup menu: New > Flex Project
Nessa primeira tela iremos definir o nome do projeto, indicando que será um projeto Flex, indicando que terá o back-end (lado Java que irá utilizar o BlazeDS) e será um projeto combinando o Flex e o WTP no mesmo projeto, onde o diretório do java será o indicado no campo (no meu caso utilizo como padrão java_src ), configurado o que for necessário, clique no botão Next >
Nessa tela é importante observar, uma dica que irá lhe poucar horas de dor de cabeça, nos campos: Context root e Context folder obrigatoriamente devem ter o mesmo nome, para que na hora da execução funcione sem necessidade de nenhuma configuração adicional.
Porém a parte ruim disto é, para quem cria, e/ou, já criou projetos Java Web no Eclipse JEE está acostumado com os projetos onde o diretório onde ficam o conteúdo de páginas é o /WebContent, então nesse projeto esse diretório será o nome definido no Context folder
Lembrando também que nessa tela você deverá indicar o locar do BlazeDS.war, que será usado na geração da estrutura do seu projeto.
Último passo da criação do projeto, aqui, eu por padrão defino:
- Framework linkage: Runtime shared library (RSL)
- Main application file: index.mxml
Depois basta clicar no botão
Com isso temos o projeto criado:
Como comentado anteriormente, podemos ver que o diretório web, ao invés do tradicional /WebContent temos o diretório nesse exemplo: /helloworld
Mas nem tudo são flores… agora que temos o projeto pronto, precisamos fazer alguns ajustes, os famosos ajustes finos…
Configurando o BlazeDS:
Primerio, vamos começar removendo os lixos (o que não iremos utilizar) no BlazeDS do projeto. Iremos começar removendo os itens:
Feito isso, iremos remover as bibliotecas (diretório /lib) do Spring que não serão utilizadas:
Ficando apenas:
Outra configuração que normalmente faço nos projetos, para evitar problemas quando trabalho com vários desenvolvedores em equipes é na configuração das propriedades do projeto onde indica o local do services-config.xml e me certifico que o locale esteja em en_US, o que me evita algumas dores de cabeça.
Para isto, clique com botão direito do mouse sobre o projeto:
Clique na opção Properties do popup menu. Com isso irá abrir uma janela com as propriedades. Nessa janela selecione o item:
Então nessa tela configure o item:
Additional compiler arguments:
-services "../helloworld/WEB-INF/flex/services-config.xml" -locale en_US
Feito isso, clique no botão OK
Para finalizar os ajustes finos ainda é necessário atualizar o web.xml da aplicação, pelo que está dentro do BlazeDS.war que foi utilizado para criar o projeto, pois de alguma forma o Wizard de criação do projeto gera um outro conteúdo para o web.xml.
Segue o conteúdo atualizado do web.xml
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 | <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <display-name>HelloWorld</display-name> <description>BlazeDS Application</description> <!-- 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> <display-name>MessageBrokerServlet</display-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> <!-- é importante que esteja descomentado --> <servlet> <servlet-name>RDSDispatchServlet</servlet-name> <display-name>RDSDispatchServlet</display-name> <servlet-class>flex.rds.server.servlet.FrontEndServlet</servlet-class> <init-param> <param-name>useAppserverSecurity</param-name> <!-- como não iremos utilizar autenticação --> <param-value>false</param-value> </init-param> <load-on-startup>10</load-on-startup> </servlet> <servlet-mapping id="RDS_DISPATCH_MAPPING"> <servlet-name>RDSDispatchServlet</servlet-name> <url-pattern>/CFIDE/main/ide.cfm</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>MessageBrokerServlet</servlet-name> <url-pattern>/messagebroker/*</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> </welcome-file-list> </web-app> |
Agora vamos colocar a mão na massa e fazer o que interessa… Como vou apenas mostrar como utilizar Remote Object, irei fazer uma comunicação bem simples entre o Flex e o Java…
Segue a classe Java do serviço:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | package com.erkobridee.helloworld.flex.service; /** * @author Erko * @description Classe de serviço * */ public class HelloWorld { public String sayHello() { return "Hello Flex 4 o/"; } public String sayHelloTo(String name) { String message = "Hello, " + name; System.out.println(message); return message; } } |
Agora precisamos cadastrar essa nossa classe como um serviço disponível no BlazeDS, e isto deverá ser feito no arquivo: remoting-config.xml
Segue a configuração do serviço:
1 2 3 4 5 | <destination id="helloWorldService"> <properties> <source>com.erkobridee.helloworld.flex.service.HelloWorld</source> </properties> </destination> |
Até aqui já temos o lado do servidor pronto, hora de ir para o lado Flex da aplicação…
Nessa nova versão do Flex existem 2 maneiras de trabalhar com os Remote Objects, a forma antiga que estamos acostumados através das mesmas tags do Flex 3
Mas vamos começar definindo a interface da aplicação:
Irei começar pela forma antiga, codificando como era feito no Flex 3, mas algo que não posso deixar de comentar aqui, utilizando o Adobe Flash Builder 4, a produtividade de velocidade de codificação estão muito mais rápidos do que na versão do Adobe Flex Builder 3…
Comentei o panel do Data Wizard e implementei os respectivos códigos para execução, conforme o código a seguir:
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 | <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" minWidth="955" minHeight="600"> <!-- ___________________________________________________________________ --> <fx:Script> <![CDATA[ import mx.controls.Alert; import mx.rpc.events.FaultEvent; import mx.rpc.events.ResultEvent; //------------------------------------------------------------------ // Handlers Remote Object formato antigo protected function roService_faultHandler(event:FaultEvent):void { Alert.show( event.fault.message ); } private function roService_sayHello_ResultHandler(event:ResultEvent):void { Alert.show( event.result as String ); } private function roService_sayHelloTo_ResultHandler(event:ResultEvent):void { Alert.show( event.result as String ); } //------------------------------------------------------------------ // evento de click nos botões : Remote Object formato antigo protected function sayHelloBtnRO_clickHandler(event:MouseEvent):void { this.roService.sayHello(); } protected function sayHelloToNameBtnRO_clickHandler(event:MouseEvent):void { this.roService.sayHelloTo(nameFieldRO.text); } //------------------------------------------------------------------ ]]> </fx:Script> <!-- ___________________________________________________________________ --> <fx:Declarations> <!-- Place non-visual elements (e.g., services, value objects) here --> <s:RemoteObject id="roService" destination="helloWorldService" fault="roService_faultHandler(event)"> <!-- esse formato é útil quando se tem um tipo de resultado para cada método --> <s:method name="sayHello" result="roService_sayHello_ResultHandler(event)"/> <s:method name="sayHelloTo" result="roService_sayHelloTo_ResultHandler(event)"/> </s:RemoteObject> </fx:Declarations> <!-- ___________________________________________________________________ --> <s:Panel x="10" y="10" width="250" title="<mx:RemoteObject>"> <s:VGroup x="0" y="0" width="100%" height="100%"> <mx:Form width="100%"> <mx:FormItem label="Name"> <s:TextInput id="nameFieldRO" text="Remote Object"/> </mx:FormItem> </mx:Form> <s:HGroup width="100%" horizontalAlign="center"> <s:Button label="sayHello" id="sayHelloBtnRO" click="sayHelloBtnRO_clickHandler(event)"/> <s:Button label="sayHelloToName" id="sayHelloToNameBtnRO" click="sayHelloToNameBtnRO_clickHandler(event)"/> </s:HGroup> </s:VGroup> </s:Panel> <!-- Por enquanto não foi implementado os códigos dessa parte <s:Panel x="268" y="10" width="250" title="Data Wizard"> <s:VGroup x="0" y="0" width="100%" height="100%"> <mx:Form width="100%"> <mx:FormItem label="Name"> <s:TextInput id="nameFieldDW" text="Data Wizard"/> </mx:FormItem> </mx:Form> <s:HGroup width="100%" horizontalAlign="center"> <s:Button label="sayHello" id="sayHelloBtnDW"/> <s:Button label="sayHelloToName" id="sayHelloToNameBtnDW"/> </s:HGroup> </s:VGroup> </s:Panel> --> </s:Application> |
Hora de testar… para isso clique com botão direito do mouse sobre o projeto e selecione a opção: Run as > Run on Server
Na janela a seguir, assumindo que você tenha baixado o Apache Tomcat 6, e que esteja disponível no seu ambiente e que não tenha nenhum outro projeto vinculado…
clique no botão Finish
Com isso basta abrir a aplicação no WebBrowser:
Clicando no botão sayHello
Clicando no botão sayHelloToName
Vimos que a códificação é exatamente a mesma que estamos acostumados, pelo menos as tags, fora a sintaxe, organização do MXML do Flex 4 ficou mais clara (pelo menos na minha opinião).
Hora de vermos a outra forma de trabalhar, que é através do Data Wizard…
Lembre-se de deixar o servidor executando…
Clique na aba Data/Services do Adobe Flash Builder
Nessa aba, clique no link Connect to Data/Service…
Nessa janela que será aberta, selecione BlazeDS e clique no botão Next >
Irá lhe aparecer esta janela, solicitando o usuário e senha. Lembrando que configuramos sem autenticação, selecione o check box No password required e clique no botão OK
Nessa janela serão exibidos todos os serviços disponíves pelo BlazeDS, então selecione o respectivo serviço (Destination), indique o pacote Service package que será o pacote onde serão gerados os códigos AS3 para uso do serviço. Feito isso, clique no botão Finish
Na aba Data/Services , agora você ve o seu serviço mapeado disponível…
O Adobe Flash Builder também te disponibiliza um meio fácil e rápido para testar o seu serviço… Basta indicar qual serviço e respectiva operação que deseja efetuar o teste.
Bom agora que já temos o suporte, basta adicionar o código de uso na nossa aplicação… e com esse novo Adobe Flash Builder é realmente muito simples de fazer isso
Uma maneira de fazer isto é, na área de desenvolvimento visual, selecionar o item, no caso o botão sayHello ir na paleta de propriedades e na definição do On click, clicar no item indicado em vermelho, então selecionar o Generate Service Call
Será aberto uma janela, onde você deverá indicar qual serviço e respectiva operação que será executada, feito isso clique no botão OK
Bom para o outro botão basta realizar o mesmo procedimento, indicando a operação sayHelloTo
Com isso o código da aplicação Flex ficou:
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 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | <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" minWidth="955" minHeight="600" xmlns:service="service.*"> <!-- ___________________________________________________________________ --> <fx:Script> <![CDATA[ import mx.controls.Alert; import mx.rpc.events.FaultEvent; import mx.rpc.events.ResultEvent; //------------------------------------------------------------------ // Handlers Remote Object formato antigo protected function roService_faultHandler(event:FaultEvent):void { Alert.show(event.fault.faultString + '\n' + event.fault.faultDetail); } private function roService_sayHello_ResultHandler(event:ResultEvent):void { Alert.show( event.result as String ); } private function roService_sayHelloTo_ResultHandler(event:ResultEvent):void { Alert.show( event.result as String ); } //------------------------------------------------------------------ // evento de click nos botões : Remote Object formato antigo protected function sayHelloBtnRO_clickHandler(event:MouseEvent):void { this.roService.sayHello(); } protected function sayHelloToNameBtnRO_clickHandler(event:MouseEvent):void { this.roService.sayHelloTo(nameFieldRO.text); } //============================================================================================ //------------------------------------------------------------------ // Handlers Data Wizard formato novo protected function helloWorldService_faultHandler(event:FaultEvent):void { Alert.show(event.fault.faultString + '\n' + event.fault.faultDetail); } protected function sayHelloResult_resultHandler(event:ResultEvent):void { Alert.show( event.result as String ); } protected function sayHelloToResult_resultHandler(event:ResultEvent):void { Alert.show( event.result as String ); } //------------------------------------------------------------------ // evento de click nos botões : Data Wizard formato novo protected function sayHelloBtnDW_clickHandler(event:MouseEvent):void { sayHelloResult.token = helloWorldService.sayHello(); } protected function sayHelloToNameBtnDW_clickHandler(event:MouseEvent):void { sayHelloToResult.token = helloWorldService.sayHelloTo(nameFieldDW.text); } ]]> </fx:Script> <!-- ___________________________________________________________________ --> <fx:Declarations> <!-- Place non-visual elements (e.g., services, value objects) here --> <s:RemoteObject id="roService" destination="helloWorldService" fault="roService_faultHandler(event)"> <!-- esse formato é útil quando se tem um tipo de resultado para cada método --> <s:method name="sayHello" result="roService_sayHello_ResultHandler(event)"/> <s:method name="sayHelloTo" result="roService_sayHelloTo_ResultHandler(event)"/> </s:RemoteObject> <!-- __________________________________ --> <!-- equivalente ao s:method sayHello --> <s:CallResponder id="sayHelloResult" result="sayHelloResult_resultHandler(event)"/> <!-- equivalente ao s:method sayHelloTo --> <s:CallResponder id="sayHelloToResult" result="sayHelloToResult_resultHandler(event)"/> <!-- equivalente ao s:RemoteObject roService --> <service:HelloWorldService id="helloWorldService" fault="helloWorldService_faultHandler(event)" showBusyCursor="true"/> </fx:Declarations> <!-- ___________________________________________________________________ --> <s:Panel x="10" y="10" width="250" title="<mx:RemoteObject>"> <s:VGroup x="0" y="0" width="100%" height="100%"> <mx:Form width="100%"> <mx:FormItem label="Name"> <s:TextInput id="nameFieldRO" text="Remote Object"/> </mx:FormItem> </mx:Form> <s:HGroup width="100%" horizontalAlign="center"> <s:Button label="sayHello" id="sayHelloBtnRO" click="sayHelloBtnRO_clickHandler(event)"/> <s:Button label="sayHelloToName" id="sayHelloToNameBtnRO" click="sayHelloToNameBtnRO_clickHandler(event)"/> </s:HGroup> </s:VGroup> </s:Panel> <s:Panel x="268" y="10" width="250" title="Data Wizard"> <s:VGroup x="0" y="0" width="100%" height="100%"> <mx:Form width="100%"> <mx:FormItem label="Name"> <s:TextInput id="nameFieldDW" text="Data Wizard"/> </mx:FormItem> </mx:Form> <s:HGroup width="100%" horizontalAlign="center"> <s:Button label="sayHello" id="sayHelloBtnDW" click="sayHelloBtnDW_clickHandler(event)"/> <s:Button label="sayHelloToName" id="sayHelloToNameBtnDW" click="sayHelloToNameBtnDW_clickHandler(event)"/> </s:HGroup> </s:VGroup> </s:Panel> </s:Application> |
Então executando a aplicação pelo Web Browser temos:
Clicando no botão sayHello
Clicando no botão sayHelloTo
E com isso finalizo este post.
Projeto para download: [HelloWorld] – projeto Adobe Flash Builder 4
O projeto está sem as libs, necessário realizar o download da versão indicada do BlazeDS e adicionar as libs no projeto.
Obs.: Essa maneira de montar projeto é apenas 1 de 3 que eu conheço, porém até o momento é a a mais rápida.








Pingback: FLEX 4 » Bruno bg + ADOBE FLEX
Pingback: [ Flerry ] Adobe AIR 2 conversando com Java local em AMF via NativeProcess - redeRIA | Agregador de noticias, artigos, tutoriais Flex, Flash, JavaFX, AJAX e Rich internet applications em geral!
Pingback: iniciando um novo projeto. » Bruno bg + ADOBE FLEX