FlexEn el artículo anterior vimos una introducción a Flex 3, con un pequeño ejemplo para dar los primeros pasos.

En esta segunda nota de introducción veremos que las aplicaciones Flex pueden comunicarse con servicios y aplicaciones en servidores para el acceso a datos. Más que esto, pueden implementar toda su lógica de negocio en objetos deplegados en un servidor de aplicaciones. Analizaremos cuáles son los mecanismos y lenguajes soportados y un ejemplo paso a paso de una implementación con Java en el servidor usando Spring como framework de aplicación.

Mecanismos de comunicación

Existen 3 mecanismos de comunicación posibles entre un cliente Flex y aplicaciones u objetos en un servidor:

  1. Servicios HTTP: se basa en intercambio de XMLs entre la aplicación flash que se ejecuta en el browser del cliente y el servidor de información que se quiera acceder. Con este mecanismo, cualquier tecnología de software que se ejecute en el servidor (php, asp, jsp, etc) puede proveer información o servir de backend para una aplicación flex.
  2. Web Services: Flex es compatible con el estandar SOAP de Webservices, por lo que puede acceder a cualquier aplicación en el servidor con esta tecnología.
  3. Remote Object Services: Utilizando un mecanismo de acceso al servidor que solo requiere de configuración, se puede acceder a los objetos remotos que se encuentran en un servidor (objetos Java, componentes ColdFusion, objetos PHP y objetos .NET) e invocar sus métodos. Esto evita que se deban exponer las funcionalidades con webservices o HTTPservices disminuyendo el costo de programación.

Remote Object Services con Java

Para acceder a Objetos Java en el servidor, debe instalarse un servicio de acceso a datos. Actualmente existen 2 implementaciones:

  1. BlazeDS : Permite la comunicación entre aplicaciones Flex y objetos remotos JAVA en el servidor. Es open source.
  2. Adobe LiveCicle Data Services: Al igual que BlazeDS permite la comunicación con aplicaciones Flex pero además incorpora diversas utilidades para la creación de servicios del lado del servidor. Mas información se puede encontrar en esta nota. Esta versión es comercial.

De esta manera, utilizando cualquiera de estas tecnologías, se pueden crear aplicaciones Flex con un modelo de negocio creado en Java ejecutandose en el servidor.

Aquí se puede ver un esquema de cómo sería la arquitectura:

arquitectura Flex y Java

Creando una aplicacion Flex/Java utilizando BlazeDS y Spring.

En la siguiente guía crearemos una aplicación que utiliza Java, Spring y BlazeDS en conjunto. La integración de estas tecnologías se hace por medio de la configuración de una clase factory (SpringFactory) creada por el equipo de Flex. Al momento de escribirse esta nota, la gente de Spring y la gente de Adobe están creando un framework de integración llamado Spring BlazeDS Integration  que promete más posibilidades a esta integración.

¿Qué necesitamos descargar?

Para poder realizar los pasos siguientes es necesario descargar:

  1. Distribución de BlazeDS 
  2. Distribución de Spring
  3. Archivos de SpringFactory

Creacion del Proyecto Flex/BlazeDS en FlexBuilder 3

Creamos el proyecto Flex con el nombre "demo1-HolaMundoBlazeDSSpring", elegimos application server Type: J2EE y tildamos la casilla "Use remote Object access service". Esto último permitirá especificar el path al war de blazeds que será incluido en el paquete de la aplicación. Click en Next.

Creacion Proyecto Flex/BlazeDS

En la siguiente pantalla, se debe indicar el servidor que se utilizará para probar la aplicación, en la opción "Target Runtime". Seleccionaremos el servidor Tomcat que tenemos instalado. Si no hubiera ninguno instalado, debe crearse uno con el botón "new".

En la opción "Flex War File" seleccionamos la ruta al war de blazeDS que descargamos previamente. Podemos dejar las demás opciones por defecto y terminamos con "Finish".

Configuracion Proyecto Flex/Java paso 2.


Creación de la aplicación Flex

El siguiente es el código de la aplicacion main.mxml. Es muy sencillo y nos sirve para ver el funcionamiento de la llamada a objetos remotos. Con aplicaciones de gran tamaño lo mejor es optar por un modelo MVC, donde los accesos a los datos o a servicios en el servidor se implementen fuera de la capa de presentación, accediendo a una clase controladora que se encargue de estas llamadas. 

 
<?xml version="1.0" encoding="utf-8"?>
<mx:Application 
xmlns:mx="http://www.adobe.com/2006/mxml" layout="horizontal" width="582" 
height="326" horizontalAlign="center" verticalAlign="middle" 
borderStyle="outset">
 
<mx:Script>
<![CDATA[
import mx.rpc.events.ResultEvent;
import mx.rpc.events.FaultEvent;
import mx.utils.ObjectUtil;
import mx.controls.Alert;
import mx.utils.StringUtil;
 
/**
 * Manejador del resultado de la llamada al servicio
 */            
private function resultHandler(event:ResultEvent):void{
    Alert.show( ObjectUtil.toString(event.result) );   
}
/**
 * Manejador del fault que pueda causar la llamada al servicio
 */
private function faultHandler(event:FaultEvent):void{
    Alert.show( ObjectUtil.toString(event.fault) );
}
]]>
 
</mx:Script>
 
<!-- Objeto remoto que se accede en el servidor.-->
<mx:RemoteObject id="ro" 
 destination="hola-mundo-java-spring"   
 result="resultHandler(event)"
 fault="faultHandler(event)"     
 endpoint="http://localhost:8080/demo1-HolaMundoFlexJava-Java/messagebroker/amf"/>
 
<mx:Panel width="457" 
    height="228" 
    layout="vertical" 
    title="Demo 1 - Flex 3 con Java en el servidor." 
    borderColor="#A7FAFF" 
    fontFamily="Arial" 
    fontWeight="bold" 
    fontSize="13" 
    horizontalAlign="center">
 
    <mx:Text text="Click para obtener un mensaje desde una clase Java" 
        fontWeight="bold" width="250"/>
        <mx:Spacer height="10"/>
        <mx:Button label="Hola Mundo!" click="ro.getHolaMundoJava()"/>
</mx:Panel>   
 
</mx:Application>
 

El siguiente fragmento de código es el que indica cómo se accederá al servicio en el servidor:

 
<!-- Objeto remoto que se accede en el servidor.-->    
<mx:RemoteObject id="ro" 
 destination="hola-mundo-java-spring"
 result="resultHandler(event)"
 fault="faultHandler(event)" 
 endpoint="http://localhost:8080/demo1-HolaMundoFlexJava-Java/messagebroker/amf"/>
 

El elemento RemoteObject define el acceso a un objeto remoto con los siguientes atributos:

  • id: identificación para ser invocado.
  • destination: servicio al que se quiere acceder en el servidor.
  • result: funcion de actionscript que manejará el resultado de la invocación.
  • fault: funcion de actionscript que manejará un eventual fallo (fault) de la invocación.
  • endpoint: url de destino, donde se encuentra el servicio que se quiere acceder.

En esta aplicacion de ejemplo, ambos handlers mostraran un mensaje con el mensaje recibido del servidor, o con una descripcion en caso de producirse un fault.

La llamada al servicio se realiza al clickear en el botón:

 
<mx:Button label="Hola Mundo!" click="ro.getHolaMundoJava()"/>
 

Esto llamará al servicio configurado en el objeto remoto con id "ro", invocando al método "getHolaMundoJava()". Notar que este método no está definido en ningún lugar de la aplicación Flex cliente, por lo tanto errores de tipeos no generan errores de compilación, con lo que se debe tener cuidado de escribir bien.

Creación del Servicio en el servidor JEE, con BlazeDS y Spring

Crearemos ahora el servicio de lado del servidor, utilizando Spring como framework de nuestra aplicación.

Incluir el Jar de Spring al Proyecto

En las propiedades del proyecto -> menu "Java EE Module Dependencies" -> agregar el jar de spring, seleccionandolo con "Add Jars".

Creacion de las clases de servicio y objeto de negocio

En este ejemplo sencillo, crearemos una clase de servicio compuesta por un objeto de negocio con un único método que devolverá la frase "Hola Mundo desde Java!". Crearemos a continuación las interfases y clases que necesitamos. Ubicarlas en los paquetes correspondientes dentro de la carpeta src:

HolaMundoFlexService.java

 
package com.dosideas.flex.demo1.service;
import com.dosideas.flex.demo1.business.HolaMundoBo;
 
public class HolaMundoFlexService {
 
    private HolaMundoBo holaMundoBo;
 
    public String getHolaMundoJava() {
        return getHolaMundoBo().decirHola();
    }
 
    //getter y setter del objeto de negocio
    ...
 
}
 

HolaMundoBo.java

 
package com.dosideas.flex.demo1.business;
 
public interface HolaMundoBo {
 
    public String decirHola();
 
} 
 

HolaMundoBoImpl.java

 
package com.dosideas.flex.demo1.business.impl;
import com.dosideas.flex.demo1.business.HolaMundoBo;
 
public class HolaMundoBoImpl implements HolaMundoBo {
 
    public String decirHola() {
        return "Hola Mundo desde Java!";
    }
}
 

Creacion de archivos de configuracion de spring

Crear el archivo applicationContext.xml en el directorio WEB-INF de la aplicación web.

 
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
 
    <!-- bean de testing para la aplicacion flex -->
    <bean name="holaMundoFlexService" 
          class="com.dosideas.flex.demo1.service.HolaMundoFlexService">  
          <property name="holaMundoBo" ref="business.HolaMundoBo" />     
    </bean>
</beans>
 

Crear el archivo de configuracion de beans de objetos de negocio "hola-mundo-business.xml" en la carpeta src (raíz de los fuentes Java) con el siguiente contenido: 

 
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
 
    <bean name="business.HolaMundoBo" 
          class="com.dosideas.flex.demo1.business.impl.HolaMundoBoImpl">
    </bean>
 
</beans>
 

Configurar el contexto de spring en la aplicación web

En el descriptor web.xml, agregar el siguiente codigo para que se reconozcan los archivos de configuración de spring. Agregaremos dos archivos de configuración, el applicationContext.xml que declarará el servicio que se proveerá a la aplicación cliente y será el punto de acceso a la aplicación y el archivo hola-mundo-business.xml que definirá los objetos de negocio que serán usados en el servicio.

 
<!-- Configuracion para el funcionamiento de spring -->
<context-param>
    <param-name>contextConfigLocation</param-name>    
    <param-value>/WEB-INF/applicationContext.xml
                 classpath:hola-mundo-business.xml
    </param-value>
</context-param> 
<listener>
    <listener-class>
        org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener>

Notar que se indican los dos archivos de configuración de beans en los valores de contextConfigLocation.

Configurar BlazeDS para que utilice el Bean de Spring "holaMundoFlexService" para responder al cliente Flex

Para que BlazeDS utilice los beans de spring hay que indicarle una clase factory que será la encargada de la instanciación de los servicios, que serán en definitiva beans de spring. Esta clase se llama SpringFactory.java y se encuentra en la distribucion de SpringFlex. Hay que agregarla al proyecto y configurarla:

Buscar esta clase en flex/samples/factories y copiarla en el paquete flex.samples.factories de nuestro proyecto, en la carpeta src (fuentes de Java, ojo no confundir con flex_src que son los fuentes de flex).

Configurar la factory en el archivo WEB-INF/flex/services-config.xml agregando:

 
<!-- factory para utilizar beans de spring -->
<factories>
    <factory id="spring" class="flex.samples.factories.SpringFactory"/>
</factories>
 

Crear el "destination" al que acceden los clientes Flex en el archivo WEB-INF/flex/remoting-config.xml (justo después del elemento default-channels)

 
<destination id="hola-mundo-java-spring">    
    <properties>           
        <factory>spring</factory>
        <!-- nombre del bean al que se quiere acceder -->
        <source>holaMundoFlexService</source>    
    </properties>
</destination>
 

Notar que acá indicamos que se utilice la factory de spring declarada en el archivo anterior. El id de este elemento es el que se indica en el atributo "destination" en la definición de objetos remotos en la aplicacion cliente flex. El elemento "source" indica el nombre del bean de spring que resolverá las peticiones a este servicio.

¡Todo listo! Probamos la aplicación

La aplicación ya está lista para ejecutarse. Seleccionamos el proyecto -> Run As -> Run on Server.

Accedemos en un navegador a la dirección: http://localhost:8080/demo1-HolaMundoBlazeDSSpring/main.html

Podremos ver el mensaje recibido desde nuestra aplicación Java en el servidor:

HolaMundo Flex/Java 

Les dejo algunas páginas para que consulten más información:

Inspiración.

"Si tú tienes una manzana y yo tengo una manzana e intercambiamos las manzanas, entonces tanto tú como yo seguiremos teniendo una manzana cada uno. Pero si tú tienes una idea y yo tengo una idea, e intercambiamos las ideas, entonces ambos tendremos dos ideas"

Bernard Shaw