Flex2 e VRaptor

Flex2 (SDK) é opensource, razão suficiente para mostrar um pequeno exemplo como usar Flex2 com VRaptor 2.x (em breve teremos uma versão com VRaptor 3 deste artigo). Vamos criar um página de login e uma lógica que verifique os dados no Servidor.

Update: Hoje em dia, no vraptor 3, voce pode fazer a integração facilmente via json diretamente

O que é Flex2?

Adobe Flex2 é um framework para criar aplicações ricas que rodam no browser. Flex2 é baseado no Flash que deve ser conhecido pelas interfaces bonitas e altamente interativas. Ele estende o Flash com um modelo de programação mais versátil e completo.

Flash Player

Para rodar uma aplicação Flex2 é preciso um plugin (flash player) para o browser. Ele funciona semelhante a JVM e abstraí todos as diferenças e incompatibilidades entre tipos e versões do browser.

Flex2 SDK

Para desenvolver uma aplicação Flex2, temos que baixar o Flex Software Development Kit ou SDK que, como eu mencionei é OpenSource. Com ele vem as ferramentas (como o compilador) e as bibliotecas básicas para criar uma aplicação.

Baixe o Flex2 SDK e descompacte-o. Na pasta bin você encontra o executável mxmlc, o compilador, que nós usaremos.

A primeira classe com Flex2/Actionscript

A linguagem do flex se chama ActionScript sua sintaxe é bem parecida com a do Java. Também tem package, import, construtores e métodos (que se chamam funções).

Vamos criar uma classe que representa nosso modelo na página de login ou seja uma classe Usuario com dois atributos, login e senha. Uma diferença é a palavra-chave “var” para definir variáveis e “function” para construtores/métodos. Além disso, o tipo da variável e o return type do método vem depois da declaração:

package modelo{
       public class Usuario {

               // class fields
               private var login:String;
               private var senha:String;

               /**
               * Constructor with parameters
               */
               public function Usuario(login:String, senha:String) {
                       this.login = login;
                       this.senha = senha;
               }

               public function getLoginParameters():Object {
                       return {"usuario.login": this.login, "usuario.senha" : this.senha};
               }

               public function toString():String {
                       return "Login: " + this.login + ", Senha: " + this.senha;
               }

       }
}

Parece uma mistura do java e javascript. Salve a classe num arquivo Usuario.as numa pasta chamada modelo.

Adobe Flex Builder é uma IDE paga (baseada no eclipse) que ajuda na criação das classes e componentes visuais.

A interface gráfica

Os componentes gráficos são definidos num arquivo xml de forma declarativa. Para criar um item num formulário para inserir o login, podemos usar:

<mx:FormItem label="Login">
      <mx:TextInput id="loginInput"/>
</mx:FormItem>

Login, Senha e um botão seria:

<mx:HBox>
    <mx:FormItem label="Login">
        <mx:TextInput id="loginInput"/>
    </mx:FormItem>
    <mx:FormItem label="Senha">
        <mx:TextInput displayAsPassword="true" id="senhaInput"/>
    </mx:FormItem>
</mx:HBox>
<mx:Button  label="login" click="sendLogin(loginInput.text,senhaInput.text);"/>

Scripts

Observe que nós usamos um evento no botão, semelhante ao Javascript. Aqui chamamos um função sendLogin( .. , .. ) com os parâmetros do login e senha. Dentro do xml podemos definir uma área para nossos funções. Basta abrir :

<mx:Script>

<![CDATA[

	public function sendLogin(login:String, senha:String):void {
		//cria modelo
		var usuario:Usuario = new Usuario(login,senha);
		//chamada http aqui
	}

]]>

</mx:Script>

Definimos a interface gráfica e um método/função para ser chamado quando o botão “login” for apertado. Falta programar a chamada http, mas vamos primeiro criar a lógica no servidor com VRaptor.

Lógica com VRaptor

Usei o blank-project do VRaptor para instalar rapidamente um projeto web pré-configurado no Eclipse.

A classe UsuarioLogic é bem parecida com a do primeiro exemplo na página principal do vraptor. Ela simula um login de uma usuario num sistema. Se for um login válido, ela devolve “ok” caso contrário “invalid”.

@Component
public class LoginLogic {

  private String autenticado = "invalid";

  @Remotable
  public void check(Usuario usuario) {

    if(usuario == null){
      return;
    }

    //simula login
    if("johann".equals(usuario.getLogin()) &amp;&amp; "12345".equals(usuario.getSenha())) {
      System.out.printf("%s é valido!", usuario.getLogin());
      this.autenticado = "ok";
    }
  }
  //ejetando "autenticado" no formato JSON
  public String getAutenticado() {
    return this.autenticado;
  }
}

e o modelo:

public class Usuario {

    private String login, senha;

  //getters e setters
}

JSON

@Remotable muda o comportamento padrão do VRaptor e devolve todos os dados ejetados (pelo getters) no formato JSON.

Por exemplo, acessando o servidor pela lógica no contexto “flex”:

http://localhost:8080/flex/login.check.ajax.logic?usuario.login=johann&usuario.senha=12345

devolveria a resposta no formato JSON:

{"autenticado":"ok"}

Chamando a lógica com flex

Vamos voltar ao flex, e programar a chamada http. Para isso o flex oferece um objeto HTTPService que pode ser declarado no xml do flex:

<mx:HTTPService
	id      = "service"
	method  = "POST"
	rootURL = "http://localhost:8080/testes/"
	result  = "onSuccess(event)"
	fault   = "onError(event)"
/>

O importante é o atributo id, com ele podemos acessar o objeto HTTPService dentro do script. O método de callback “onSuccess” será automaticamente chamado depois do request, “onError” quando um erro acontecer. O princípio dos callbacks é também usado no javascript/ajax. Então voltando à função sendLogin, podemos fazer a chamada completa.

Corelib

No método onSuccess(event) converteremos a resposta Http para um objeto JSON. Por padrão o flex (ainda) não sabe lidar com JSON, por isso temos que disponibilzar uma biblioteca que dará essa possibilidade . A corelib do flex2 vem com suporte para JSON, e tem que ser baixado separadamente. Depois de descompactar, adicione o arquivo corelib.swc da pasta bin na pasta lib do Flex SDK.

Script completo

Finalmente o script intereiro que usa a classe Usuario, o HTTPService com os métodos de callback e a classe JSON da corelib:

<mx:Script>

<![CDATA[

	import mx.controls.Alert;
	import mx.rpc.events.ResultEvent;
	import mx.rpc.events.FaultEvent;
	import mx.utils.ObjectUtil;
	import mx.rpc.http.HTTPService
	import com.adobe.serialization.json.JSON;
	import modelo.Usuario;

	public function sendLogin(login:String, senha:String):void {
		//cria modelo
		var usuario:Usuario = new Usuario(login,senha);

		//seta o url
        service.url = "login.check.ajax.logic";

		//faz a chamada passando os parâmetros
        service.send(usuario.getLoginParameters());
    }

    public function onSuccess(event:ResultEvent):void {

		//cria String baseado no resultado
		var rawData:String = String(event.result);
		//cria um objeto json
		var respostaNoFormatoJSON:Object = JSON.decode(rawData);

		//login ok?
		if(respostaNoFormatoJSON["autenticado"] == "ok") {
			Alert.show("Bem vindo!");
		} else {
			Alert.show("Usuário não existe");
		}
    }

    public function onError(event:FaultEvent):void {
        Alert.show(ObjectUtil.toString(event.fault));
    }

]]>
</mx:Script>

Compilação dos arquivos flex

O xml todo (com script e interface gráfica) deve estar num arquivo login.mxml. Temos a seguinte estrutura:

login.mxml
modelo/Usuario.as

Execute na linha de comando usando o compilador do flex (que está na pasta bin do sdk):

...pasta-para-flex-sdk/bin/mxmlc login.mxml

Isso vai criar a aplicação ou seja um arquivo login.swf.

Rodando no servidor

O login.swf deve estar no servidor, você pode abrir o login.swf localmente mas a chamada Http acaba num security exception (é bom para testar o método onError(..)).

No nosso exemplo:

http://localhost:8080/flex/login.swf

Toda configuração do servidor é padrão tomcat/

Tags: , ,

10 Comentários

  1. David Michael 07/05/2007 at 17:08 #

    Muito Bom! Aparentemente muito menos burocrático que o RemoteObject do Flex.
    Acredito que assim eu poderia facilmente reutilizar um sistema feito com o vRaptor com o flex, a unica mudança aparente seria anotar todos os métodos com @Remotable, ou estou enganado?

  2. Luiz Aguiar 08/05/2007 at 07:07 #

    Muito interessante, e será que para uma interface mais “comple[ta|xa]” sem o Flex Builder, acho que da um bom trabalho hein? Já chegou fazer algo maior com o Flex sem o Builder?
    valeu!

  3. Sergio Lopes 08/05/2007 at 23:40 #

    Engraçado mas não gosto desse Flex… O resultado final é impecavel, inegavel, mas o desenvolvimento ainda nao me agrada…

  4. Nico Steppat 09/05/2007 at 08:19 #

    @David

    Vc pode aproveitar a grande maioria do seu código, mas acredito que vc precisa alterar “coisinhas” para migrar p/ flex.

    @Luiz

    Acredito que realmente fica dificil sem IDE (também não desenvolvo java no vi 😀 ). mas como o flex sdk virou open-source, talvez também surgirão outras ferramentas/plugins.

    @Sergio

    O desenvolvimento é tão diferente? além das telas bonita e ricas, flex tira a dor de cabeça com as incompatibilidades entre os browsers …

  5. Alexandre Ferreira 07/02/2008 at 17:17 #

    Nico, bom post!
    Mas você enxerga a necessidade de usar um framework Java MVC para essa união?
    Estou usando Flex + Java aqui na Michelin(Trabalho) e não estou vendo a necessidade de usar Java + Flex + Framework MVC(Struts, SpringMVC, VRaptor) .

    Abraço, Alexandre Ferreira!

  6. Nico Steppat 07/02/2008 at 19:33 #

    Olá Alexandre,

    Nao precisa mesmo. A desvantagem é que vc fica preso com o flex no lado do client E no servidor.

    abracos

  7. Pablo Faria 28/05/2008 at 02:05 #

    Como faço para recuperar uma List e apresentar em um Grid no flex com JSON?

    Não Consegui fazer…

  8. Marco 13/02/2010 at 19:54 #

    Gostaria da versão deste post para o vRaptor 3 e flexbuilder 3

  9. Wesley 19/11/2012 at 16:01 #

    Não gosto desse tipo de desenvolvimento. Mas ótima explicação.

Deixe uma resposta