Flex2 e VRaptor
Por Nico Steppat em 07/05/07Flex2 (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.
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/servlet.
Download
Disponibilizo o pequeno exemplo como download
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?
Comment by David Michael — May 7, 2007 @ 5:08 pm
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!
Comment by Luiz Aguiar — May 8, 2007 @ 7:07 am
Engraçado mas não gosto desse Flex… O resultado final é impecavel, inegavel, mas o desenvolvimento ainda nao me agrada…
Comment by Sergio Lopes — May 8, 2007 @ 11:40 pm
@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 …
Comment by Nico Steppat — May 9, 2007 @ 8:19 am
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!
Comment by Alexandre Ferreira — February 7, 2008 @ 5:17 pm
Olá Alexandre,
Nao precisa mesmo. A desvantagem é que vc fica preso com o flex no lado do client E no servidor.
abracos
Comment by Nico Steppat — February 7, 2008 @ 7:33 pm
Como faço para recuperar uma List e apresentar em um Grid no flex com JSON?
Não Consegui fazer…
Comment by Pablo Faria — May 28, 2008 @ 2:05 am
[...] [Blog Caelum] Flex2 e VRaptor – Scale nine CSS para Flex – [blogblogs] tag Apollo – 30 Minutes Flex Test-Drive for Java [...]
Pingback by Air & Flex: links interessantes — July 17, 2008 @ 12:16 am
Gostaria da versão deste post para o vRaptor 3 e flexbuilder 3
Comment by Marco — February 13, 2010 @ 7:54 pm