Daily Archives: May 2, 2010

Hola Mundo con Spring BlazeDS y Flex

Hola amigos, acá comparto un ejemplo de como desarrollar un “Hola mundo” con Spring BlazeDS y con Flex.

Vamos directo al código :)

Maven

Las principales cosas que definimos en el archivo maven son:

  1. Dependencias JSP/Servlet.
  2. Dependencias para el Spring framework.
  3. Dependencias para el Spring BlazeDS.
  4. Plugin para compilar java con 1.5 que tiene soporte para anotaciones.
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    ...
 
    <!-- defining some properties -->
    <properties>
        <org.springframework.version>3.0.0.RELEASE</org.springframework.version>
    </properties>
 
    <!-- dependencies -->
    <dependencies>
        ...
        <!-- jsp/servlet -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
            <scope>provided</scope>
        </dependency>
 
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.1</version>
            <scope>provided</scope>
        </dependency>
 
        <!-- spring 3 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.flex</groupId>
            <artifactId>spring-flex</artifactId>
            <version>1.0.3.RELEASE</version>
        </dependency>
 
        <!-- blazeds -->
        <dependency>
            <groupId>com.adobe.blazeds</groupId>
            <artifactId>blazeds-core</artifactId>
            <version>3.2.0.3978</version>
        </dependency>
        <dependency>
            <groupId>com.adobe.blazeds</groupId>
            <artifactId>blazeds-proxy</artifactId>
            <version>3.2.0.3978</version>
        </dependency>
        <dependency>
            <groupId>com.adobe.blazeds</groupId>
            <artifactId>blazeds-opt</artifactId>
            <version>3.2.0.3978</version>
        </dependency>
        <dependency>
            <groupId>com.adobe.blazeds</groupId>
            <artifactId>blazeds-remoting</artifactId>
            <version>3.2.0.3978</version>
        </dependency>
 
        ...
    </dependencies>
    <build>
        <finalName>helloblazeds</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.5</source>
                    <target>1.5</target>
                </configuration>
            </plugin>
            ...    
        </plugins>
    </build>
</project>

web.xml

En el web.xml tenemos:

  1. Definición de un Filtro para soportar caracteres UTF8.
  2. Mapeo de la servlet de Spring para manejar cualquier pedido que pase por /messagebroker/*.
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="ifm_service_catalog" version="2.4"
         xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
                             http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
 
    <display-name>Hello World with SpringBlazeDS</display-name>
 
    <!-- filter -->
    <filter>
        <filter-name>encoding-filter</filter-name>
        <filter-class>
            org.springframework.web.filter.CharacterEncodingFilter
        </filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
 
    <filter-mapping>
        <filter-name>encoding-filter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
 
    <!-- servlet -->
 
    <servlet>
        <servlet-name>spring-flex</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/flex-servlet-context.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
 
    <servlet-mapping>
        <servlet-name>spring-flex</servlet-name>
        <url-pattern>/messagebroker/*</url-pattern>
    </servlet-mapping>
 
    <!-- Welcome file list -->
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>
</web-app>

flex-servlet-context.xml, services-config.xml y remoting-config.xml

El flex-servlet-context.xml es bien sencillo. Solo le indicamos a Spring que paquete escanear para buscar clases anotadas y la definición del bean MessageBroker para la integración con Flex.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:flex="http://www.springframework.org/schema/flex"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context
                           http://www.springframework.org/schema/context/spring-context.xsd
                           http://www.springframework.org/schema/flex
                           http://www.springframework.org/schema/flex/spring-flex-1.0.xsd">
    <context:component-scan base-package="test.flex" />
    <flex:message-broker/>
</beans>

El services-config.xml sirve para definir los canales y servicios que serán soportados. Véase también que en el canal estamos indicando como vienen los pedidos, en este caso “/messagebroker/amf”

<?xml version="1.0" encoding="UTF-8"?>
<services-config>
    <services>
        <service-include file-path="remoting-config.xml" />
        <default-channels>
           <channel ref="my-amf-channel"/>
        </default-channels>
    </services>
 
    <channels>
        <channel-definition id="my-amf-channel" class="mx.messaging.channels.AMFChannel">
            <endpoint url="http://{server.name}:{server.port}/{context.root}/messagebroker/amf"
                      class="flex.messaging.endpoints.AMFEndpoint"/>
        </channel-definition>
    </channels>
    <logging>
        <target class="flex.messaging.log.ConsoleTarget" level="Error">
            <properties>
                <prefix>[BlazeDS]</prefix>
                <includeDate>false</includeDate>
                <includeTime>false</includeTime>
                <includeLevel>false</includeLevel>
                <includeCategory>false</includeCategory>
            </properties>
            <filters>
                <pattern>Endpoint.*</pattern>
                <pattern>Service.*</pattern>
                <pattern>Configuration</pattern>
            </filters>
        </target>
    </logging>
    <system>
        <redeploy>
            <enabled>false</enabled>
        </redeploy>
    </system>
</services-config>

En el remoting-config.xml definimos el adaptar java para AMF.

<?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-channel"/>
    </default-channels>
</service>

Clase SayHello

La siguiente clase esta anotada como servicio y también como destinación remota para AMF :)

package test.flex;
 
import java.io.*;
import java.util.List;
import org.springframework.flex.remoting.RemotingDestination;
import org.springframework.stereotype.Service;
 
@Service("SayHello")
@RemotingDestination
public class SayHello {
 
    public String hello(){
        return "Hola Mundo";
    }
}

Finalmente el código en Flex :)

En la aplicación Flex tenemos:

  1. Definición de object RemoteObject.
  2. Un botón pulsante para llamar al metodo hello().
  3. Definición de dos funciones flex para manejar la respuesta en caso de éxito y fallo de la llamada.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<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;
 
/**
 * Response handler
 */            
private function resultHandler(event:ResultEvent):void{
    Alert.show( ObjectUtil.toString(event.result) );   
}
/**
 * Failure handler
 */
private function faultHandler(event:FaultEvent):void{
    Alert.show( ObjectUtil.toString(event.fault) );
}
]]>
 
</mx:Script>
 
<!-- Remote object that is accessed from the server.-->
<mx:RemoteObject id="remoteObject" 
 destination="SayHello"   
 result="resultHandler(event)"
 fault="faultHandler(event)"     
 endpoint="http://localhost:8080/helloblazeds/messagebroker/amf"/>
 
<mx:Panel width="457" 
    height="228" 
    layout="vertical" 
    title="Hola Mundo con AMF/Flex y BlazeDS" 
    horizontalAlign="center">
    <mx:Button label="Hola Mundo!" click="remoteObject.hello()"/>
</mx:Panel>    		
</mx:Application>