Adobe Flash Builder + Flex 4 + BlazeDS 4

domingo, 28/03/2010 5:39 am  

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…

 

EclipseGalileoWelcome

Para este post serão necessários os items:

Eclipse Galileo JEE

Adobe Flash Builder 4 plugin

Apache Tomcat 6

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:

EclipseGaligeoFlashBuilderPerspective

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

Flex4ProjectWizard_01 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 >

 Flex4ProjectWizard_02 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.

Flex4ProjectWizard_03 Ú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:

Flex4ProjectView Como comentado anteriormente, podemos ver que o diretório web, ao invés do tradicional /WebContent temos o diretório nesse exemplo: /helloworld

Flex4ProjectView_02 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:

Flex4ProjectView_03 Feito isso, iremos remover as bibliotecas (diretório /lib) do Spring que não serão utilizadas:

Flex4ProjectView_04

Ficando apenas:

Flex4ProjectView_05Outra 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:

Flex4ProjectView_06Clique na opção Properties do popup menu. Com isso irá abrir uma janela com as propriedades. Nessa janela selecione o item:

Flex4ProjectView_07 Então nessa tela configure o item:

Flex4ProjectView_08 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.

Flex4ProjectView_09 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

Flex4ProjectView_10 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 ou através dos Data Wizard presente no Adobe Flash Builder que gera para nós um suporte para trrabalhar com os Remote Objects…

 

Mas vamos começar definindo a interface da aplicação:

 Flex4ProjectView_11

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:

?View Code ACTIONSCRIPT3
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

Flex4ProjectView_12

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…

Flex4ProjectView_13

clique no botão Finish

 

Com isso basta abrir a aplicação no WebBrowser:

Flex4ProjectView_14

Clicando no botão sayHello

Flex4ProjectView_15

Clicando no botão sayHelloToName

Flex4ProjectView_16

 

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

Flex4ProjectView_17 Nessa aba, clique no link Connect to Data/Service…

Flex4ProjectView_18 Nessa janela que será aberta, selecione BlazeDS e clique no botão Next >

Flex4ProjectView_19

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

Flex4ProjectView_20Nessa 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 

Flex4ProjectView_21 Na aba Data/Services , agora você ve o seu serviço mapeado disponível…

Flex4ProjectView_22

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

Flex4ProjectView_23 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

Flex4ProjectView_24

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

Flex4ProjectView_25

Com isso o código da aplicação Flex ficou:

?View Code ACTIONSCRIPT3
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:

Flex4ProjectView_26

Clicando no botão sayHello

Flex4ProjectView_27

Clicando no botão sayHelloTo

Flex4ProjectView_28

 

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.

, , , , , ,

Este post foi escrito por:

- que escreveu 500 post(s).


Entre em contato