Sunday, May 16, 2010

Integrating Spring Flex

Looking for better Adobe BlazeDS and Java platform integration, I would like to recommend one very useful project from SpringSource portfolio: Spring Flex (or Spring BlazeDS integration). It's pretty easy to start with and, moreover, you could integrate it with other projects like Spring Framework and Spring Security.

Let's start with simple configuration.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:context="http://www.springframework.org/schema/context"
  xmlns:flex="http://www.springframework.org/schema/flex"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="
      http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context-2.5.xsd  
      http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
      http://www.springframework.org/schema/flex
      http://www.springframework.org/schema/flex/spring-flex-1.0.xsd">

   <context:annotation-config />   
   <context:component-scan base-package="org.example.flex" />
   
   <flex:message-broker id="_messageBroker" services-config-path="/WEB-INF/flex/services-config.xml">
       <flex:message-service default-channels="default-amf, secure-amf" />     
   </flex:message-broker> 
  
</beans>
Basically, those few lines of code do all routine work to start Adobe BlazeDS MessageBroker servlet (to handle AMF protocol), publish your classes (annotated as @RemotingDestination) as remote objects to be accessible by Flex clients.

Adobe BlazeDS configuration, referenced here as /WEB-INF/flex/services-config.xml is pretty standard. It includes bare minimum enough to run simple application.
  • /WEB-INF/flex/services-config.xml
  • <?xml version="1.0" encoding="UTF-8"?>
    <services-config>
        <services>
            <service-include file-path="remoting-config.xml" />
            <service-include file-path="proxy-config.xml" />
            <service-include file-path="messaging-config.xml" />     
    
         <default-channels>
             <channel ref="default-amf"/>
         </default-channels>
        </services>
    
        <channels>
            <channel-definition id="default-amf" class="mx.messaging.channels.AMFChannel">
                <endpoint url="http://{server.name}:{server.port}/{context.root}/messagebroker/amf/" class="flex.messaging.endpoints.AMFEndpoint"/>
            </channel-definition>
    
            <channel-definition id="secure-amf" class="mx.messaging.channels.SecureAMFChannel">
                <endpoint url="https://{server.name}:9400/{context.root}/messagebroker/amfsecure/" class="flex.messaging.endpoints.SecureAMFEndpoint"/>
            </channel-definition>
        </channels>
    </services-config>
    
  • /WEB-INF/flex/messaging-config.xml
  • <?xml version="1.0" encoding="UTF-8"?>
    <service id="message-service" class="flex.messaging.services.MessageService">
        <adapters>
            <adapter-definition id="actionscript" class="flex.messaging.services.messaging.adapters.ActionScriptAdapter" default="true"/>
            <adapter-definition id="jms" class="flex.messaging.services.messaging.adapters.JMSAdapter" />
        </adapters>
    </service>
    
  • /WEB-INF/flex/remoting-config.xml
  • <?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>
    </service>
    
  • /WEB-INF/flex/proxy-config.xml
  • <?xml version="1.0" encoding="UTF-8"?>
    <service id="proxy-service" class="flex.messaging.services.HTTPProxyService">
        <properties>
            <connection-manager>
                <max-total-connections>100</max-total-connections>
                <default-max-connections-per-host>2</default-max-connections-per-host>
            </connection-manager>
            <allow-lax-ssl>true</allow-lax-ssl>
        </properties>
    
        <adapters>
            <adapter-definition id="http-proxy" class="flex.messaging.services.http.HTTPProxyAdapter" default="true"/>
            <adapter-definition id="soap-proxy" class="flex.messaging.services.http.SOAPProxyAdapter"/>
        </adapters>
    
        <destination id="DefaultHTTP">
         <properties>
             <url>/{context.root}/default.jsp</url>
         </properties>
        </destination>
    </service>
    
Configuration part is done. Let's create a simple remote object class.
package org.example.flex;

import org.springframework.flex.remoting.RemotingDestination;
import org.springframework.stereotype.Service;

@Service
@RemotingDestination( value = "simpleService", channels = { "default-amf", "secure-amf" } )
public class SimpleService {
    public Boolean test() {
 return Boolean.TRUE;
    }
}
That's it! SimpleService is declared as simple POJO with @RemotingDestination annotation and will be discovered by Spring configuration and automatically published as remote object for "default-amf" and "secure-amf" channels.

Integrating Spring Security is again just a few configuration lines. Here is an example:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:security="http://www.springframework.org/schema/security"
  xmlns:context="http://www.springframework.org/schema/context"
  xmlns:flex="http://www.springframework.org/schema/flex"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="
 http://www.springframework.org/schema/context
 http://www.springframework.org/schema/context/spring-context-2.5.xsd  
 http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
 http://www.springframework.org/schema/flex
 http://www.springframework.org/schema/flex/spring-flex-1.0.xsd
 http://www.springframework.org/schema/security 
 http://www.springframework.org/schema/security/spring-security-3.0.xsd">

    <context:annotation-config />   
    <context:component-scan base-package="org.example.flex" />

    <bean id="authenticationProvider" class="org.example.flex.CustomAuthenticationProvider" /> 

    <security:authentication-manager alias="authenticationManager">
        <security:authentication-provider ref="authenticationProvider" />  
    </security:authentication-manager> 
  
    <flex:message-broker id="_messageBroker" services-config-path="/WEB-INF/flex/services-config.xml">
       <flex:message-service default-channels="default-amf, secure-amf" />     
       <flex:secured authentication-manager="authenticationManager" />        
    </flex:message-broker>   
</beans>
Spring Flex also provides a bunch of interesting features such as exception translators. It worthwhile to look at this project if you are developing Flex applications with Adobe BlazeDS.

2 comments:

Christian said...

What do you mean by @RemoteObject tag? I do not see that on your POJO code nor I could find it in my project.

Andriy Redko said...

Hi Chrisitian,

My mistake. It should be @RemotingDestination annotation, not a @RemoteObject. I updated the post. Thank you.