Archive for julho, 2010



Parte 1Parte 2Parte 3Parte 4.1Parte 4.2

Nesta parte do tutorial, vamos fazer um exemplo um pouquinho mais complicado que o anterior. Iremos criar quatro serviços, um para cada operação matemática. Cada um dos serviços vai receber dois números como parâmetro e vai retornar o valor da operação. Iremos também montar a interface gráfica para utilizar estes serviços e todo o mapeamento da parte em Flex para o backend em Java. Então vamos lá!

Antes de iniciarmos a implementação dos serviços, primeiro vamos configurar nossa aplicação para que quando executada, a página do swf seja aberta automaticamente. Não podemos configurar para abrir o HTML diretamente via web.xml, então teremos que usar o nosso index.jsp para fazer o redirecionamento. Para isso, basta adicionar um <meta http-equiv=”Refresh” …/> no nosso index.jsp. Segue então o código completo do index.jsp, onde já removi o “Hello World!” e o título da página. Esta página vai servir apenas como ponto de entrada da aplicação.

index.jsp

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
 "http://www.w3.org/TR/html4/loose.dtd">

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <meta http-equiv="Refresh" content="0; url=swf/IntegracaoFlexJavaGUI.html">
    </head>
    <body>
    </body>
</html>

Com o index.jsp atualizado, teste novamente sua aplicação. Agora a página do swf vai ser carregada automaticamente. Vamos aos serviços.

No NetBeans, com o projeto aberto, vamos no pacote “servicos” que criamos na parte anterior e vamos criar uma nova classe, com o nome de “ServicosCalculadora”. Nesta classe iremos implementar quatro métodos: double somar(double n1, double n2), double subtrair(double n1, double n2), double multiplicar(double n1, double n2) e double dividir( double n1, double n2). A implementação de cada método é muito simples. Eles irão retornar o resultado da operação denotada pelo nome do método sob os operandos. Segue então a implementação da classe ServicosCalculadora:

servicos.ServicosCalculadora.java

package servicos;

/**
 * Serviços de cálculo.
 *
 * @author David Buzatto
 */
public class ServicosCalculadora {

    public double somar( double n1, double n2 ) {
        return n1 + n2;
    }

    public double subtrair( double n1, double n2 ) {
        return n1 - n2;
    }

    public double multiplicar( double n1, double n2 ) {
        return n1 * n2;
    }

    public double dividir( double n1, double n2 ) {
        return n1 / n2;
    }

}

Note que não estamos nos preocupando com divisão por zero. Legal! O segundo passo agora é editar o remoting-config.xml informar tanto ao BlazeDS quanto ao compilador do Flex que a classe ServicosCalculadora é uma classe que contém serviços. Abra então o remoting-config.xml e adicione mais um destination que agora aponta para a nova classe e de um id para ele. Segue o remoting-config.xml completo:

remoting-config.xml

<?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="testeServicos">
        <properties>
            <source>servicos.ServicosTeste</source>
        </properties>
    </destination>

    <destination id="servicosCalculadora">
        <properties>
            <source>servicos.ServicosCalculadora</source>
        </properties>
    </destination>

</service>

Ótimo, a parte do lado Java está pronta. Simples não é? Vamos para o Flash Builder agora. Vamos reorganizar nossa interface, pois vamos utilizá-la a mesma tela para todos os exemplos. Na interface Design, vamos criar um painel (categoria Layout da paleta de componentes) e arrastar o botão do primeiro exemplo para dentro dele. Criaremos outro painel então para conter os componentes do exemplo que estamos implementando agora. Note que do lado direito da interface do Flash Builder existe a aba de propriedades do componente que está selecionado no momento. Lá você pode alterar as propriedades do componente que está editando. Veja como ficou:

 

Figura 1

Interface do exemplo de Calculadora

 

Temos então os campos para os números que serão calculados, alguns radios para as operações, um botão para chamar o serviço de cálculo e um campo para o resultado. Para mentermos um padrão, segue o código do mxml que temos até o momento. Já defini os ids dos componentes.

IntegracaoFlexJavaGUI.mxml

<?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" minWidth="955" minHeight="600">

	<fx:Script>
		<![CDATA[
			import mx.controls.Alert;
			import mx.rpc.events.FaultEvent;
			import mx.rpc.events.ResultEvent;

			private function botaoExecutarClick( event: Event ): void {
				servicos.imprimirMensagem();
			}

			private function imprimirMensagemFault( event: FaultEvent ): void {
				Alert.show( "Ocorreu um erro...", "ERRO" );
			}

			private function imprimirMensagemResult( event: ResultEvent ): void {
				Alert.show( "Serviço executado com sucesso!", "Mensagem" );
			}

		]]>
	</fx:Script>

	<fx:Declarations>

		<s:RemoteObject
			id="servicos"
			destination="testeServicos"
			showBusyCursor="true">

			<s:method
				name="imprimirMensagem"
				fault="imprimirMensagemFault(event)"
				result="imprimirMensagemResult(event)"/>

		</s:RemoteObject>
		<s:RadioButtonGroup id="grupoOperacoes"/>

	</fx:Declarations>

	<s:Panel x="11" y="10" width="250" height="200" title="Testes Serviços (ServicosTeste.java)">
		<s:Button x="15" y="13" label="Executar" click="botaoExecutarClick(event)"/>
	</s:Panel>
	<s:Panel x="269" y="10" width="250" height="241" title="Calculadora (ServicosCalculadora.java)">
		<s:Label x="12" y="20" text="Número 1:"/>
		<s:Label x="13" y="50" text="Número 2:"/>
		<s:TextInput x="79" y="14" width="64" id="campoN1"/>
		<s:TextInput x="80" y="44" width="63" id="campoN2"/>
		<s:Label x="13" y="102" text="Operação:"/>
		<s:RadioButton x="77" y="84" label="+" groupName="grupoOperacoes" selected="true" id="radioSomar"/>
		<s:RadioButton x="111" y="84" label="-" groupName="grupoOperacoes" id="radioSubtrair"/>
		<s:RadioButton x="77" y="110" label="*" groupName="grupoOperacoes" id="radioMultiplicar"/>
		<s:RadioButton x="111" y="110" label="/" groupName="grupoOperacoes" id="radioDividir"/>
		<s:Label x="10" y="184" text="Resultado:"/>
		<s:TextInput x="79" y="176" id="campoResultado" width="159"/>
		<s:Button x="10" y="141" label="Calcular!" width="228"/>
	</s:Panel>
</s:Application>

Da mesma forma que fizemos para o primeiro exemplo, precisamos agora definir o <s:RemoteObject> que vai apontar para a nossa classe e mapear todos os métodos. Como exercício, logo abaixo do <s:RemoteObject> do exemplo anterior, declare no novo <s:RemoteObject> e os quatro métodos. Lembre-se que o destination tem que ser o mesmo que declaramos no remoting-config.xml (servicosCalculadora). Para os eventos fault e result de cada um dos métodos, aponte para as funções calculadoraFault(event) e calculadoraResult(event) respectivamente. Vamos utilizar os mesmo tratadores de eventos para cada um dos métodos. Em cada um deles, coloque um Alert, indicando um erro ou que o cálculo foi executado. Terminou? Veja se ficou parecido com isso aqui:

IntegracaoFlexJavaGUI.mxml

<?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" minWidth="955" minHeight="600">

	<fx:Script>
		<![CDATA[
			import mx.controls.Alert;
			import mx.rpc.events.FaultEvent;
			import mx.rpc.events.ResultEvent;

			private function botaoExecutarClick( event: Event ): void {
				servicos.imprimirMensagem();
			}

			private function imprimirMensagemFault( event: FaultEvent ): void {
				Alert.show( "Ocorreu um erro...", "ERRO" );
			}

			private function imprimirMensagemResult( event: ResultEvent ): void {
				Alert.show( "Serviço executado com sucesso!", "Mensagem" );
			}

			private function calculadoraFault( event: FaultEvent ): void {
				Alert.show( "Ocorreu um erro...", "ERRO" );
			}

			private function calculadoraResult( event: ResultEvent ): void {
				Alert.show( "Serviço executado com sucesso!", "Mensagem" );
			}

		]]>
	</fx:Script>

	<fx:Declarations>

		<s:RemoteObject
			id="servicos"
			destination="testeServicos"
			showBusyCursor="true">

			<s:method
				name="imprimirMensagem"
				fault="imprimirMensagemFault(event)"
				result="imprimirMensagemResult(event)"/>

		</s:RemoteObject>

		<s:RemoteObject
			id="calculadora"
			destination="servicosCalculadora"
			showBusyCursor="true">

			<s:method
				name="somar"
				fault="calculadoraFault(event)"
				result="calculadoraResult(event)"/>

			<s:method
				name="subtrair"
				fault="calculadoraFault(event)"
				result="calculadoraResult(event)"/>

			<s:method
				name="multiplicar"
				fault="calculadoraFault(event)"
				result="calculadoraResult(event)"/>

			<s:method
				name="dividir"
				fault="calculadoraFault(event)"
				result="calculadoraResult(event)"/>

		</s:RemoteObject>

		<s:RadioButtonGroup id="grupoOperacoes"/>

	</fx:Declarations>

	<s:Panel x="11" y="10" width="250" height="200" title="Testes Serviços (ServicosTeste.java)">
		<s:Button x="15" y="13" label="Executar" click="botaoExecutarClick(event)"/>
	</s:Panel>
	<s:Panel x="269" y="10" width="250" height="241" title="Calculadora (ServicosCalculadora.java)">
		<s:Label x="12" y="20" text="Número 1:"/>
		<s:Label x="13" y="50" text="Número 2:"/>
		<s:TextInput x="79" y="14" width="64" id="campoN1"/>
		<s:TextInput x="80" y="44" width="63" id="campoN2"/>
		<s:Label x="13" y="102" text="Operação:"/>
		<s:RadioButton x="77" y="84" label="+" groupName="grupoOperacoes" selected="true" id="radioSomar"/>
		<s:RadioButton x="111" y="84" label="-" groupName="grupoOperacoes" id="radioSubtrair"/>
		<s:RadioButton x="77" y="110" label="*" groupName="grupoOperacoes" id="radioMultiplicar"/>
		<s:RadioButton x="111" y="110" label="/" groupName="grupoOperacoes" id="radioDividir"/>
		<s:Label x="10" y="184" text="Resultado:"/>
		<s:TextInput x="79" y="176" id="campoResultado" width="159"/>
		<s:Button x="10" y="141" label="Calcular!" width="228"/>
	</s:Panel>
</s:Application>

Certo, configuramos nosso objeto remoto, mapeamos os métodos, registramos os eventos de erro (FaultEvent) e de execução bem sucedida (ResultEvent). Falta agora fazer funcionar. Para isso iremos criar um método para tratar o evento click do botão, e neste método verificar qual a operação a ser executada e chamar o método correspondente do serviço. Para poupar espaço, vou colocar apenas o código do método que trata o evento click e como o código do botão “Calcular!” deve ficar.

private function botaoCalcularClick( event: Event ): void {

	/*
	 * Declaração de duas variáveis do tipo Number que recebem
	 * a conversão em número do texto dos seus respectivos campos.
	 * Note que não há nenhuma validação.
	 */
	var n1: Number = Number( campoN1.text );
	var n2: Number = Number( campoN2.text );

	/*
	 * grupoOperacoes é um RadioButtonGrupo que está relacionado
	 * aos quatro radios criados. O propriedade selectedValue retorna
	 * o valor da propriedade label do radio selecionado no momento.
	 * Perceba que em ActionScript, nós podemos fazer switch com Strings
	 * diferentemente do Java (até a versão 6.0) onde isso não é suportado
	 */
	switch ( grupoOperacoes.selectedValue.toString() ) {

		case "+":
			calculadora.somar( n1, n2 );
			break;

		case "-":
			calculadora.subtrair( n1, n2 );
			break;

		case "*":
			calculadora.multiplicar( n1, n2 );
			break;

		case "/":
			calculadora.dividir( n1, n2 );
			break;

	}

}

Código do botão “Calcular!”:

<s:Button x="10" y="141" label="Calcular!" width="228" click="botaoCalcularClick(event)"/>

Teste e veja se está ocorrendo algum erro. Se estive, corrija. Perceba que ainda não tratamos o resultado retornado. Isso será realizado no método que trata o ResultEvent, pois só quando ele é executado significa que o método remoto (nosso serviço) foi executado corretamente. Então vamos fazer a modificação necessária no método calculadoraResult para que o resultado do serviço seja colocado no campo de resultado. Segue então o método alterado:

private function calculadoraResult( event: ResultEvent ): void {

	/*
	 * a propriedade result do objeto event (do tipo ResultEvent)
	 * contém o valor de retorno do método remoto que foi executado
	 * essa propriedade é do tipo Object, então caso haja a necessidade
	 * de se converter o valor retornado, é necessário saber que tipo que está
	 * sendo retornado.
	 *
	 * Como os números no ActionScript também são objetos, aqui
	 * não é feita nenhuma conversão, só chamando o método toString()
	 * do valor, retornando assim a representação em String do número retornado.
	 */
	var valor: Object = event.result;
	campoResultado.text = valor.toString();

	Alert.show( "Serviço executado com sucesso!", "Mensagem" );

}

Teste para verificar se está funcionando. Caso após executar o projeto do NetBeans o aplicativo swf não tiver sido atualizado, segure a tecla Shift e clique no botão atualizar do seu navegador. Assim ele é forçado a recarregar do “zero” o swf. Não se esqueça de sempre salvar o projeto no Flash Builder para que o projeto seja recompilado. Segue então o código mxml final deste exemplo:

IntegracaoFlexJavaGUI.mxml

<?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" minWidth="955" minHeight="600">

	<fx:Script>
		<![CDATA[
			import mx.controls.Alert;
			import mx.rpc.events.FaultEvent;
			import mx.rpc.events.ResultEvent;

			private function botaoExecutarClick( event: Event ): void {
				servicos.imprimirMensagem();
			}

			private function imprimirMensagemFault( event: FaultEvent ): void {
				Alert.show( "Ocorreu um erro...", "ERRO" );
			}

			private function imprimirMensagemResult( event: ResultEvent ): void {
				Alert.show( "Serviço executado com sucesso!", "Mensagem" );
			}

			private function calculadoraFault( event: FaultEvent ): void {
				Alert.show( "Ocorreu um erro...", "ERRO" );
			}

			private function calculadoraResult( event: ResultEvent ): void {

				/*
				 * a propriedade result do objeto event (do tipo ResultEvent)
				 * contém o valor de retorno do método remoto que foi executado
				 * essa propriedade é do tipo Object, então caso haja a necessidade
				 * de se converter o valor retornado, é necessário saber que tipo que está
				 * sendo retornado.
				 *
				 * Como os números no ActionScript também são objetos, aqui
				 * não é feita nenhuma conversão, só chamando o método toString()
				 * do valor, retornando assim a representação em String do número retornado.
				 */
				var valor: Object = event.result;
				campoResultado.text = valor.toString();

				Alert.show( "Serviço executado com sucesso!", "Mensagem" );

			}

			private function botaoCalcularClick( event: Event ): void {

				/*
				 * Declaração de duas variáveis do tipo Number que recebem
				 * a conversão em número do texto dos seus respectivos campos.
				 * Note que não há nenhuma validação.
				 */
				var n1: Number = Number( campoN1.text );
				var n2: Number = Number( campoN2.text );

				/*
				 * grupoOperacoes é um RadioButtonGrupo que está relacionado
				 * aos quatro radios criados. O propriedade selectedValue retorna
				 * o valor da propriedade label do radio selecionado no momento.
				 * Perceba que em ActionScript, nós podemos fazer switch com Strings
				 * diferentemente do Java (até a versão 6.0) onde isso não é suportado
				 */
				switch ( grupoOperacoes.selectedValue.toString() ) {

					case "+":
						calculadora.somar( n1, n2 );
						break;

					case "-":
						calculadora.subtrair( n1, n2 );
						break;

					case "*":
						calculadora.multiplicar( n1, n2 );
						break;

					case "/":
						calculadora.dividir( n1, n2 );
						break;

				}

			}

		]]>
	</fx:Script>

	<fx:Declarations>

		<s:RemoteObject
			id="servicos"
			destination="testeServicos"
			showBusyCursor="true">

			<s:method
				name="imprimirMensagem"
				fault="imprimirMensagemFault(event)"
				result="imprimirMensagemResult(event)"/>

		</s:RemoteObject>

		<s:RemoteObject
			id="calculadora"
			destination="servicosCalculadora"
			showBusyCursor="true">

			<s:method
				name="somar"
				fault="calculadoraFault(event)"
				result="calculadoraResult(event)"/>

			<s:method
				name="subtrair"
				fault="calculadoraFault(event)"
				result="calculadoraResult(event)"/>

			<s:method
				name="multiplicar"
				fault="calculadoraFault(event)"
				result="calculadoraResult(event)"/>

			<s:method
				name="dividir"
				fault="calculadoraFault(event)"
				result="calculadoraResult(event)"/>

		</s:RemoteObject>

		<s:RadioButtonGroup id="grupoOperacoes"/>

	</fx:Declarations>

	<s:Panel x="11" y="10" width="250" height="200" title="Testes Serviços (ServicosTeste.java)">
		<s:Button x="15" y="13" label="Executar" click="botaoExecutarClick(event)"/>
	</s:Panel>
	<s:Panel x="269" y="10" width="250" height="241" title="Calculadora (ServicosCalculadora.java)">
		<s:Label x="12" y="20" text="Número 1:"/>
		<s:Label x="13" y="50" text="Número 2:"/>
		<s:TextInput x="79" y="14" width="64" id="campoN1"/>
		<s:TextInput x="80" y="44" width="63" id="campoN2"/>
		<s:Label x="13" y="102" text="Operação:"/>
		<s:RadioButton x="77" y="84" label="+" groupName="grupoOperacoes" selected="true" id="radioSomar"/>
		<s:RadioButton x="111" y="84" label="-" groupName="grupoOperacoes" id="radioSubtrair"/>
		<s:RadioButton x="77" y="110" label="*" groupName="grupoOperacoes" id="radioMultiplicar"/>
		<s:RadioButton x="111" y="110" label="/" groupName="grupoOperacoes" id="radioDividir"/>
		<s:Label x="10" y="184" text="Resultado:"/>
		<s:TextInput x="79" y="176" id="campoResultado" width="159"/>
		<s:Button x="10" y="141" label="Calcular!" width="228" click="botaoCalcularClick(event)"/>
	</s:Panel>
</s:Application>

Na próxima (e última) parte do nosso tutorial, iremos ver como trabalhar com objetos criados por nós mesmos, enviando e recebendo esses objetos entre as camadas feitas em ActionScript (swf) e Java (com suporte do BlazeDS). Utilizaremos banco de dados também, fazendo então um exemplo completo de um CRUD (Create Read Update Delete).

Espero que estejam gostando!

Parte 1Parte 2Parte 3Parte 4.1Parte 4.2

Anúncios

Parte 1Parte 2Parte 3Parte 4.1Parte 4.2

Olá. Nesta parte do tutorial vamos ver onde baixar o Flash Builder, como criar um novo projeto, como “amarrar” este projeto ao projeto criado na primeira parte e por fim como criar um serviço simples e consumi-lo. Então, vamos lá!

Primeiramente você precisará baixar o Flash Builder (antigo Flex Builder), que é uma IDE especializada na criação de RIAs (Rich Internet Application) em Flash (você já deve saber disso hehe). Internamente o Flash Builder utiliza o Flex SDK (que por sua vez é gratuíto) para compilar os arquivos fonte do projeto em um .swf que conterá a interface gráfica da aplicação. Neste tutorial estou abordando o uso da IDE para facilitar o aprendizado. Acessanto esse link, você pode baixar a versão trial do Flash Builder 4 (versão que estou usando). São disponibilizadas duas versões, uma que é um Plugin para o Eclipse, e outra que é Standalone (é um Eclipse com o plugin já instalado). Como estamos trabalhando com o NetBeans para construir nosso backend, então estarei utilizando a versão Standalone, mesmo porque não sou usuário do Eclipse e não sou muito fã também.

Já baixou? Já instalou? Ótimo! Mão na massa agora 😀

Com o Flash Builder aberto, crie um novo projeto: File > New > Flex Project. Feito isso, a janela New Flex Project será exibida. Vamos preenchê-la da seguinte forma:

  • Project name: IntegracaoFlexJavaGUI – perceba que mantive o nome do projeto do NetBeans, colocando a sufixo GUI.
  • Project Location: desmarque o “Use default location”, pois iremos guardar o projeto no mesmo diretório onde estamos salvando o projeto do NetBeans. No meu caso, eu salvei o projeto do NetBeans em C:\Users\David\Documents\Java\Flex, sendo assim, o caminho para salvar o projeto do Flash Builder vai ficar C:\Users\David\Documents\Java\Flex\IntegracaoFlexJavaGUI
  • Application type: Web – estamos desenvolvendo para Web e não para o AIR. Só para contextualizar, o AIR é basicamente uma plataforma para execução de projetos do Flex em ambiente desktop, como uma aplicação convencional.
  • Flex SDK version: vamos usar o default, que é o Flex SDK 4.0 para o Flash Builder 4. Nada impede que outros SDKs sejam instalados, caso você queira usar algum mais antigo.
  • Server technology: Como estamos trabalhando com Java, vamos escolher J2EE.
    • Marque a opção “Use remote object access service” caso não esteja marcado.
    • Nós vamos utilizar o BlazeDS. Não expliquei no tutorial anterior o que é o BlazeDS, então lá vai. O BlazeDS implementa um protocolo chamado AMF (Action Message Format), que é utilizado na tarefa de serializar e deserializar objetos. Nossa aplicação em Flex vai enviar objetos ActionScript via AMF para a nossa aplicação Java. O BlazeDS vai deserializar esses objetos em objetos Java. O inverso também ocorrerá, ou seja, criaremos objetos Java, mandaremos via BlazeDS (serializando em AMF) para a aplicação em Flex, que por sua vez vai deserializá-los. Legal não? O LifeCycle Data Services é como o BlazeDS, só que mais robusto e é pago. Ah, além do Blaze e do LifeCycle que são implementações em Java, existem diversas outras implementações para outras linguagens.

 

Figura 1

Criando o projeto no Flash Builder

 

Com tudo preenchido, clique em Next. O próximo passo deve ser preenchido da seguinte forma:

  • Root folder: Este campo deve ser preenchido com o caminho do diretório que contém o diretório WEB-INF/flex. No meu caso, o caminho seria C:\Users\David\Documents\Java\Flex\IntegracaoFlexJava\web. Note que estamos apontando para o projeto do NetBeans e na pasta web estão contidas as pastas META-INF, WEB-INF e swf.
  • Root URL: Este campo deve ser preenchido com o endereço da raiz da aplicação em execução. Caso você esteja usando o Tomcat na porta padrão definida pelo NetBeans (8084), este campo deve ser preenchido com o seguinte valor: http://localhost:8084/IntegracaoFlexJava/. Perceba que normalmente o Tomcat ou outro servidor que manterá suas aplicações em produção rodam em outra porta. O padrão do Tomcat é a 8080. Então você tem duas opções. 1ª configurar o Tomcat do NetBeans para rodar na porta 8080, assim você não terá problemas quando for colocar a aplicação em produção. 2ª (não recomento) trocar a porta do Tomcat de produção para 8084. Existe a necessidade de colocar o endereço correto porque o Flex vai usar esse endereço para compilar o endereço dos serviços que iremos criar.
  • Context root: Esse campo define a raiz do contexto. Neste exemplo, a raiz é /IntegracaoFlexJava. Note que é o final do endereço do Root URL.
  • Output foler: Neste campo é definido onde o resultado da compilação do projeto no Flash Builder será colocado. Lembra da pasta swf que criamos? Queremos então que o Flash Builder jogue os .swfs gerados dentro daquela pasta. Então, no meu caso, o caminho ficou C:\Users\David\Documents\Java\Flex\IntegracaoFlexJava\web\swf

 

Figura 2

Segundo passo na criação do projeto

 

Por fim, clique em Finish. O novo projeto será criado. Por padrão, o Flash Builder vai criar um arquivo mxml que será o ponto de partida para a execução da aplicação (chamado de Default Application). No nosso caso, o arquivo gerado se chama IntegracaoFlexJavaGUI.mxml. Note que também por padrão é exibido o código do arquivo. Logo acima, podemos mudar para a visualização do Design do arquivo em questão.

 

Figura 3

Botão design

 

Clicando no botão Design, você poderá ver o editor gráfico da interface. À esquerda há uma paleta com os componentes gráficos. Arraste um botão para o Design para podermos ver o que está acontecendo quando executamos nosso projeto.

 

Figura 4

Um botão inserido na aplicação

 

Note que o objetivo deste tutorial não é ensinar a trabalhar com o Flex nem com o Flash Builder, mas sim, ajudar na integração com a camada escrita em Java. Sendo assim, não ficarei detalhando componentes o tempo todo.

Salve o arquivo que está aberto. Sempre que salvar, o Flash Builder vai compilar todo o projeto novamente, gerando os .swfs. Sendo assim, volte agora para o NetBeans e expanda a pasta swf que foi criada no tutorial anterior. Percebe que foram gerados diversos arquivos.

 

Figura 5

Arquivos gerados dentro do NetBeans

 

Esses arquivos sempre serão gerados automaticamente, então não há necessidade de se preocupar. Os arquivos principais no nosso caso são o IntegracaoFlexJavaGUI.html e o IntegracaoFlexJavaGUI.swf. O primeiro é a página HTML que vai ser usada para executar o segundo. Vamos testar então. No NetBeans, execute o projeto (F6 ou flecha verde). A página “Hello World!” ainda será exibida. Agora mude o endereço para http://localhost:8084/IntegracaoFlexJava/swf/IntegracaoFlexJavaGUI.html e acesse. Você vai ver que será exibida a aplicação.

Legal não é? A aplicação está rodando dentro do Tomcat. Temos dois ambientes separados, um para a infraestrutura em Java no NetBeans e um para a construção da interface gráfica no Flash Builder. Vamos agora começar a trabalhar com os serviços. Primeiro vamos criar um serviço que, quando acessado, simplesmente direciona para a saída padrão, via System.out.println(), uma mensagem. Depois iremos melhorar a idéia e testar outras possibilidades, e no final, na quarta parte do tutorial, faremos um exemplo envolvendo a transferência de objetos entre as duas camadas criadas.

Vamos ao serviço então?

No projeto do NetBeans, vá em Source Packages e crie um novo pacote chamado “servicos”. Neste pacote, crie uma classe chamada “ServicosTeste”. Nesta classe, crie um método chamado imprimirMensagem que em seu corpo simplesmente executa o método System.out.println( “mensagem aqui…” ). Veja a Figura abaixo.

 

Figura 6

Primeiro servico

 

servicos.ServicosTeste.java

package servicos;

/**
 *
 * @author David
 */
public class ServicosTeste {

    public void imprimirMensagem() {
        System.out.println( "Serviço rodando! Sim senhor!" );
    }

}

Cada método definido na classe criada será um serviço, mas para que esses métodos sejam reconhecidos como serviços, precisamos configurar o arquivo remoting-config.xml, dizendo ao Flash Builder que ao compilar o projeto, a classe ServicosTeste contém serviços. Abra então o arquivo remoting-config.xml que está dentro da pasta WEB-INF/flex do projeto do NetBeans. No arquivo, antes da última tag </service> insira o seguinte trecho de código:

<destination id="testeServicos">
    <properties>
        <source>servicos.ServicosTeste</source>
    </properties>
</destination>

Com isso dizemos ao compilador do Flex (que será chamado pelo Flash Builder) que a classe ServicosTeste – que está dentro do pacote servicos – é uma classe que contém serviços. Perceba que definimos um identificador para o destination. Esse id será importante quando formos chamar o serviço pela aplicação desenvolvida no Flash Builder.

Recaptulando: criamos uma classe no NetBeans que conterá nossos serviços. Criamos o método imprimirMensagem que é o nosso primeiro serviço. Editamos o arquivo remoting-config.xml para dizer que a classe que criamos contém serviços. Agora vamos no Flash Builder para vermos como fazemos para chamar o serviço criado.

Voltando então ao Flash Builder, volte para a edição do código fonte do arquivo mxml que foi gerado. Para isso, basta clicar no botão Source (do lado do botão Design). Apague o comentátio dentro da tag <fx:Declarations>. É entre as tags <fx:Declarations> e </fx:Declarations> que iremos declarar nossos serviços. Para declarar os serviços, utilizaremos a tag <s:RemoteObject>. Segue o código que deve ficar dentro de <fx:Declarations>.

<s:RemoteObject
    id="servicos"
    destination="testeServicos"
    showBusyCursor="true">

    <s:method
        name="imprimirMensagem"
        fault=""
        result=""/>

</s:RemoteObject>

Na tag <s:RemoteObject> definimos a propriedade id (que usaremos dentro do código para executar os serviços), a propriedade destination (lembra do destination do remoting-config.xml?) e se queremos que o cursor apareça como ocupado durante a execução de algum serviço. Dentro da tag <s:RemoteObject>, definimos então os métodos, que serão os nossos servicos. Para isso, usa-se a tag <s:method>. Na propriedade name colocamos o nome do método (tem que ser igual ao da classe em Java). As propriedades fault e result eu explico daqui há pouco.

Pois bem, temos o servico configurado tanto do lado do cliente (Flex) quanto do lado do servidor (BlazeDS), agora só falta executar. Lembra do botão que criamos na interface? Ele é representado pela tag <s:Button>. Edite seu botão disso:

<s:Button x="10" y="10" label="Button"/>

Para isso:

<s:Button x="10" y="10" label="Executar" click="botaoExecutarClick(event)"/>

O que fizemos? Primeiro trocamos o label do botão para “Executar” ao invés de “Button”. Segundo, registramos um método (ou função, você escolhe como chamar) para tratar o evento de clicar no botão. Precisamos implementar esse método. Para isso, antes da tag <fx:Declarations>, iremos colocar código fonte ActionScript. Para fazer isso dentro do código do mxml, usados a tag <fx:Script>. Veja como ficou:

<fx:Script>
    <![CDATA[
        private function botaoExecutarClick( event: Event ): void {
            servicos.imprimirMensagem();
        }
    ]]>
</fx:Script>

Note que dentro do método botaoExecutarClick, nós chamamos o <s:RemoteObject> que declaramos (o id era servicos, lembra?) e chamamo o método que foi definido (imprimirMensagem). Com isso feito, salve seu arquivo, vá no NetBeans e execute novamente o projeto. Após executar, troque o endereço novamente para http://localhost:8084/IntegracaoFlexJava/swf/IntegracaoFlexJavaGUI.html e acesse. Clique no botão executar.  Vá agora no NetBeans e veja a saída do Tomcat (logo abaixo na IDE, na aba Apache Tomcat 6.0.26). Se tudo deu certo, o println com a mensagem definida dentro de imprimirMensagem deve ter executado e a mensagem vai estar na saída do Tomcat.

Deu certo? Ótimo. Não deu? Verifique o que faltou. Até agora conseguimos chamar um serviço bem simples. Ainda não trocamos mensagens entre o servidor e o cliente, mas você verá que isso é muito fácil também. Por enquanto, vamos finalizar o que já fizemos. Você se lembra das propriedades fault e result do método (<s:method>) que foi definido no <s:RemoteObject>? Pois bem, essas duas propriedades definem respectivamente um método para tratar algum problema na execução do serviço e um método para tratar a execução bem sucedida do serviço.

Vamos então implementar esses métodos. Eles simplesmente mostrarão uma mensagem. A seguir, o arquivo IntegracaoFlexJavaGUI.mxml completo:

IntegracaoFlexJavaGUI.mxml

<?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" minWidth="955" minHeight="600">

    <fx:Script>
        <![CDATA[
            import mx.controls.Alert;
            import mx.rpc.events.FaultEvent;
            import mx.rpc.events.ResultEvent;

            private function botaoExecutarClick( event: Event ): void {
                servicos.imprimirMensagem();
            }

            private function imprimirMensagemFault( event: FaultEvent ): void {
                Alert.show( "Ocorreu um erro...", "ERRO" );
            }

            private function imprimirMensagemResult( event: ResultEvent ): void {
                Alert.show( "Serviço executado com sucesso!", "Mensagem" );
            }

        ]]>
    </fx:Script>

    <fx:Declarations>

        <s:RemoteObject
            id="servicos"
            destination="testeServicos"
            showBusyCursor="true">

            <s:method
                name="imprimirMensagem"
                fault="imprimirMensagemFault(event)"
                result="imprimirMensagemResult(event)"/>

        </s:RemoteObject>

    </fx:Declarations>

    <s:Button x="10" y="10" label="Executar" click="botaoExecutarClick(event)"/>

</s:Application>

Faça as modificações necessárias, salve o projeto do Flash Builder e execute o projeto do NetBeans de novo. Aponte para a URL  http://localhost:8084/IntegracaoFlexJava/swf/IntegracaoFlexJavaGUI.html e teste. Toda vez que clicar no botão, o serviço será executado e o método que trata a execução bem sucedida (imprimirMensagemResult) vai ser executado.

Bem, esta parte já está ficando muito grande. Na próxima parte do tutorial iremos fazer uma calculadora onde enviaremos os operandos e executaremos a operação desejada. Isso pode ser feito no cliente, mas vamos testar a chamada a serviços com passagem de parâmetros e recebimento de valores. Assim que fizermos esse exemplo, partiremos para a última parte do tutorial, onde iremos trabalhar com objetos mais complexos.

Espero que estejam gostando 🙂

Parte 1Parte 2Parte 3Parte 4.1Parte 4.2


Parte 1Parte 2Parte 3Parte 4.1Parte 4.2

Hoje em dia existem diversas bibliotecas e/ou frameworks que apoiam os desenvovedores na tarefa de construir interfaces gráficas para aplicações Web, sendo que a maioria delas são baseadas em JavaScript e/ou em Flash. Tenho certa familiaridade com algumas delas e por isso decidi montar esse tutorial para ajudar quem tiver interesse em aprender como fazer a integração entre uma interface criada em Flex com um backend escrito em Java. Vou apresentar da forma mais simples possível, sem utilizar frameworks MVC, tentando apenas puxar o fio da meada para você que quer começar a aprender a trabalhar com Flex.

Este tutorial será dividido em algumas partes e nessa primeira parte vou tratar da configuração do NetBeans. Então vamos lá! Mãos na massa! Para essa parte do tutorial vamos precisar de:

Alguns detalhes quanto à instalação de cada um dos itens citados acima:

  • NetBeans 6.9 – Recomendo que você faça o download da versão completa do NetBeans (a última coluna na página de download). No primeiro passo na instalação, o instalador lhe dará a opção de escolher quais componentes deseja instalar. Eu recomendo que você escolha a opção para instalar o Tomcat. Prefiro o Tomcat para desenvolvimento;
  • BlazeDS 4.x – O BlazeDS é que vai fazer a ponte entre o .swf gerado no Flash Builder e a nossa infraestrutura em Java. Quando for fazer o download, existem três pacotes: Turnkey, binary distribution e source. Baixe o segundo pacote, o binary distribution (cerca de 4.1MB). O pacote Turnkey vem com um servidor para testar o BlazeDS enquanto no source vem o código fonte, eles serão desnecessários.

Note que ainda não entraremos em detalhes relacionados ao Flash Builder (Antigo Flex Builder). Com tudo instalado e pronto, vamos começar. O primeiro passo é criar um projeto no NetBeans e prepará-lo para a integração. Primeiramente, vamos criar um novo projeto Web no NetBeans:

  • File
    • New Project…
      • Categories: Java Web
      • Projects: Web Application

 

Figura 1

Criando um novo projeto Web no NetBeans

 

  • Next
    • Project Name: IntegracaoFlexJava
    • Project Location: escolha onse será salvo o seu projeto
    • Marque a opção “Use Dedicated Folder for Storing Libraries”, com isso, os .jars que utilizaremos no nosso projeto ficarão contidos na estrutura do projeto, permitindo que o projeto seja compactado e enviado para qualquer pessoa. Por padrão, o NetBeans vai sugerir .\lib. Recomendo que deixe assim.
    • Marque a opção “Set as Main Project

 

Figura 2

Continuação da criação do projeto no NetBeans

 

  • Next
    • Server: Apache Tomcat 6.0.26
    • O restante das opções não precisam ser alteradas. Veja Figura abaixo

 

Figura 3

Continuação da criação do projeto no NetBeans

 

  • Finish

Pronto, o projeto vai ser criado e aberto no seu NetBeans. Por padrão, o index.jsp será aberto no editor. Note que estou utilizando o NetBeans em inglês, sendo assim, caso esteja utilizando em português, utilize as figuras como guia caso tenha dificuldades. Outro detalhe é que a versão usada no NetBeans é a 6.9, sendo assim, se você estiver usando alguma versão mais antiga, algumas coisas podem ser um pouco diferentes.

Com o projeto criado, vamos passar para a configuração do BlazeDS dentro do projeto do NetBeans. Lembra do pacote do BlazeDS que você baixou? O nome dele é parecido com blazeds-bin-4.x.x.xxxx.zip. Independente da versão baixada (no meu caso foi a 4.0.0.14931), descompacte o arquivo. Note que no pacote existem dois arquivos: blazeds.war e blazeds-bin-readme.html. Lembre sempre que estou tendo como base a versão que usei.

Um arquivo com extensão WAR (Web ARchive) é um arquivo .zip (claro, com extensão alterada) que contém uma aplicação Web em Java. Sabendo disso, precisamos “pegar” algumas coisas dessa aplicação e copiar para o nosso projeto. Sendo assim, renomeie o arquivo blazeds.war para blazeds.zip e decompacte-o.

Feito isso, vamos primeiro preparar a biblioteca do BlazeDS dentro do nosso projeto. No NetBeans, com a árvore do projeto aberta, procure pela pasta Libraries.

 

Figura 4

Pasta Libraries do projeto do NetBeans

 

Clique com o botão direito na pasta Libraries e escolha Add Library. Uma janela abrirá:

 

Figura 5

Bibliotecas do Projeto

 

Essa janela exibe todas as bibliotecas que estão configuradas dentro do projeto, sendo que elas não estão necessariamente inseridas na aplicação que será gerada. Vamos então criar a biblioteca para o BlazeDS. Clique no botão Create. No diálogo que aparecerá, coloque o nome da biblioteca (Library Name) como BlazeDS-4.0.0 (ou o nome que você desejar) e no tipo da biblioteca (Library Type) escolha Class Libraries e clique em OK. A janela Customize Library abrirá.

 

Figura 6

Janela Customize Library

 

Clique em Add JAR/Foder. Um outro diálodo abrirá. Lembra que você descompactou o blazeds.zip (que era blazeds.war)? Pois bem, procure onde você o descompactou e entre na pasta WEB-INF/lib. Note que aparecerão diversos .jars. Selecione todos e clique em Add JAR/Folder.

 

Figura 7

Escolhendo os .jars do blazeds.zip (blazeds.war)

 

O NetBeans vai perguntar se você quer mesmo criar a pasta para a biblioteca. Responda que sim. O diálogo Customize Library aparecerá novamente, agora com os .jars inseridos na biblioteca. Clique em OK.

 

Figura 8

.jars selecionados e inseridos na biblioteca

 

Ao clicar no OK, o diálogo Add Library aparcerá novamente, só que agora a nova biblioteca aparecerá na lista.

 

Figura 9

Janela Add Library com a nova biblioteca

 

Selecione-a e clique em Add Library. Perceba que fazendo isso, a biblioteca será inserida na estrutura do projeto. Se você expandir a pasta Libraries do projeto, verá que todos aqueles .jars que estão configurados na biblioteca que foi criada vão aparecer.

 

Figura 10

.jars adicionados na estrutura do projeto

 

Perceba que com isso inserimos a biblioteca BlazeDS no nosso projeto e no pacote que será gerado posteriormente para implantação da aplicação no servidor. Entretanto, ainda faltam alguns detalhes que precisamos nos preocupar. Quando utilizamos o BlazeDS, nós criamos serviços que serão expostos pela nossa aplicação. Esses serviços são implementados em classes, mas é necessário que o tanto o BlazeDS quanto o compilador do Flex saibam quais classes implementam esses serviços. Para isso, são utilizados diversos arquivos de configuração. Vamos copiá-los para nosso projeto agora. Procure a pasta WEB-INF do projeto, clique com o botão direito nela e escola New > Folder.

 

Figura 11

Criando uma nova pasta em WEB-INF

 

Um diálogo irá aparecer, perguntando o nome da pasta que será criada. Entre com o nome “flex” (sem as aspas) e clique em OK.

 

Figura 12

Pasta "flex" criada

 

Com isso feito, novamente vá aonde você descompactou o blazeds.zip (antigo blazeds.war), entre na pasta WEB-INF\flex, selecione todos os arquivos e dê um Ctrl+C ou botão direito, copiar.

 

Figura 13

Copiando os arquivos de configuração do Flex

 

Com os arquivos copiados, agora volte ao NetBeans, clique com o botão direito na pasta flex que você criou e escolha Paste (colar). Os arquivos serão copiados para a pasta.

 

Figura 14

Arquivos de configuração do Flex copiados para o projeto do NetBeans

 

Estamos quase cabando. Vamos agora modificar o web.xml do nosso projeto para configurar o gerenciador de mensagens do BlazeDS. Para isso, vá novamente no pacote que você descompactou e na pasta WEB-INF procure pelo arquivo web.xml. Abrá-o para edição. Selecione o conteúdo a partir do comentário “<!– Http Flex Session attribute and binding listener support –>” até a linha antes do do código <welcome-file-list>. Copie o texto selecionado (Ctrl+C), abra o web.xml do projeto dentro do NetBeans. O web.xml dentro do NetBeans possui uma interface gráfica para configuração. Não iremos utilizá-la agora, pois vamos editar o código XML diretamente. Para isso, clique no botão XML acima no editor.

 

Figura 15

Edição do web.xml

 

Cole o código que foi copiado do web.xml do pacote descompactado na linha entre </session-config>e <welcome-file-list>. Por fim, apague os trechos de código que estão comentados. No final, seu web.xml deve ter a seguinte aparência:

 

Figura 16

web.xml final

 

Falta pouco! Ainda no web.xml, remova a tag display-name dentro da tag servlet (<display-name>MessageBrokerServlet</display-name>). O código final do web.xml pode ser visto abaixo.

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>

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

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

Da mesma forma que você criou a pasta “flex” dentro de WEB-INF, crie agora uma pasta chamada “swf” (sem aspas) na raiz do projeto (no mesmo nível de META-INF, WEB-INF e index.jsp).

 

Figura 17

Pasta "swf"

 

Posteriormente iremos configurar o Flash Builder para compilar nosso projeto em Flex e copiar os arquivos gerados para esta pasta.

O nosso último passo antes de testar o projeto é configurar o commons-logging que é é utilizado pelo BlazeDS. Para isso, primeiro vamos preparar onde iremos guardar o arquivo de configuração. Clique com o botão direito no mouse na raiz do projeto e escola Properties (último item da lista).

 

Figura 18

Acessando as propriedades do projeto

 

Com isso, a janela de propriedades do projeto abrirá. Por padrão, o item Sources estará selecionado, caso não esteja, selecione-o. Na opção sources, clique em Add Folder da área Source Package Folders.

 

Figura 19

Propriedades do projeto

 

A janela Add Source Folder irá aparecer. Nela, clique no botão destacado em vermelho na Figura abaixo e dê o nome de “logging” (sem aspas) ao diretório criado. Tecle enter para aceitar a mudança no nome do diretório, selecione-o e clique em Open.

 

Figura 20

Novo diretório de fontes

 

Feito isso, a janela de propriedades do projeto irá voltar a ser mostrada e note que o novo diretório será listado. Clique duas vezes no logging que aparece na coluna Label da tabela e dê o nome de “Configurações Logging” (sem aspas) e tecle Enter para aceitar a modificação.

 

Figura 21

Editando o label do diretório de logging

 

Por fim, clique no botão OK da janela de propriedades. Esse label que foi configurado será utilizado para mostrar essa nova pasta dentro da estrutura do projeto.

 

Figura 22

Configurações de logging dentro do projeto

 

Com isso feito, vamos agora copiar o arquivo de configuração de logging para dentro desta pasta. Vá novamente (última vez!) onde você descompactou o blazeds.zip, entre em WEB-INF/classes e copie o arquivo commons-logging.properties para a pasta que você criou dentro do NetBeans.

 

Figura 23

Arquivo de configurações de logging copiado

 

Nossa última tarefa (prometo!) é configurar para que nosso projeto não seja implantado no servidor cada vez que salvarmos algum arquivo. Isso previne que o Tomcat trave caso hajam muitos deploys seguidos. Para isso, acesse novamente as propriedades do projeto, ná na opção Run e desmarque a opção Deploy on Save e dê OK.

 

Figura 24

Desligando o deploy on save

 

Para finalizar esta parte do tutorial, pressione F6 ou então clique na flecha verde do NetBeans para compilar e executar o projeto (botão direito no projeto e Run também funciona). Se tudo estiver correto, o navegador abrirá e uma página com um “Hello World!” será exibida. Caso tenha ocorrido algum problema, revise o tutorial para verificar onde errou e tente novamente.

Na próxima parte do tutorial iremos baixar, configurar e utilizar o Flash Builder 4 para criarmos nossa primeira interface e fazer a comunicação com a camada em Java.

Grande abraço! Espero que tenha gostado 😉

Parte 1Parte 2Parte 3Parte 4.1Parte 4.2

%d blogueiros gostam disto: