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()) && "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/