Mitch Pronschinske is a Senior Content Analyst at DZone. That means he writes and searches for the finest developer content in the land so that you don't have to. He often eats peanut butter and bananas, likes to make his own ringtones, enjoys card and board games, and is married to an underwear model. Mitch is a DZone Zone Leader and has posted 2573 posts at DZone. You can read more from them at their website. View Full User Profile

Spring BlazeDS Integration with Flex 4 Final

03.23.2010
| 26459 views |
  • submit to reddit
For more than a year, SpringSource and Adobe have fostered a partnership aimed at optimizing the integration between Spring and BlazeDS.  The Spring BlazeDS Integration project succeeded in bringing Flex front ends and Spring back ends together seamlessly.  Christophe Coenraets, a technical evangelist for Adobe, gives an overview of the Spring BlazeDS integration with Flex 4, which recently went GA.  Whether you're a Spring developer that's thinking about learning Flex, or a Flex developer that wants to learn Spring, you can benefit from knowing how to integrate these best-of-breed frameworks for rich, sophisticated web applications.

BlazeDS is a powerful, server-based Java remoting and web messaging technology that enables developers to easily connect to back-end distributed data and push data in real-time to Adobe Flex and Adobe AIR.  Flex 4 can already access back end data via HTTPService (The Flex HTTPService is similar to XMLHttpRequest in Ajax) or WebService components.  With BlazeDS, Flex applications have remoting services for invoking Java object methods, message services for publishing messages and subscribing to a message destination, and proxy services that allow cross domain service requests in a secure and controlled manner.  BlazeDS is deployed as a set of JAR files within your web application.  Developers using the Spring Blaze DS integration should be aware that Spring's various modules may be harnessed in the building of remote objects as well.  

Flex Application Access to Spring Beans
Without Spring BlazeDS integration, you would need to configure BlazeDS remote objects in the remoting-config.xml file located in WEB-INF\flex to start accessing Spring beans from a Flex client .  This example shows how you would expose the ProductService Java class to remote availability for a Flex application:
<destination id="product">
<properties>
<source>my.package.ProductService</source>
</properties>
</destination>
The logical name used is "product" and the destination allows Flex to invoke the public methods of ProductService.  Here is Christophe Coenraets's minimalist Flex application used to populate a DataGrid with a product list.  The list is procured by remotely invoking the findAll() method of the ProductService class:
<?xml version="1.0" encoding="utf-8"?>
<s:Application
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<fx:Declarations>
<s:RemoteObject id="ro" destination="productService"/>
</fx:Declarations>
<s:layout>
<s:VerticalLayout/>
</s:layout>
<mx:DataGrid dataProvider="{ro.findAll.lastResult}" />
<s:Button label="Get Data" click="ro.findAll()"/>

</s:Application>
BlazeDS instantiates and manages the life cycles of the remote objects defined in the remoting-config.xml file, but this is counter to Spring's methodology, which lets the container instantiate components.  The trick is to find the best arrangement when integrating Spring and BlazeDS so that you can leverage the data services of BlazeDS while letting the Spring container manage the config, instantiation, and life cycles of the remote objects.  Still, the Spring BlazeDS integration projects has a much better way of doing things.

Spring Factory: the old way to integrate
BlazeDS is an integration mechanism based on the Factory pattern, meaning you can plug a custom factory into a destination's definition to let another subsystem manage the remote object's instantiation and life cycle.  The factory approach has some disadvantages which lead to the Spring BlazeDS integration: The dependency lookup approach runs counter to the Spring DI approach, the objects have to be configured twice, the overall system config is dispersed over many files, and integration is only possible through basic remoting without security and messaging.

Spring BlazeDS Integration
The Spring Blaze DS integration project is aimed at removing some of these disadvantages in running a Flex client with a Spring back end.  The project makes BlazeDS cooperate with Spring's management paradigms.  The MessageBroker in BlazeDS is configured and bootstrapped as a Spring-managed bean requiring no web.xml configuration.  Flex messages are routed through the Spring DispatcherServlet to the MessageBroker.  Remote objects are configured in the application context config file.  Messaging destinations are configured in the "Spring Way", and Spring security integration lets you provide security credentials from within a Flex app and secures Spring-managed beans exposed as remote objects just like you would in Spring.

After you configure Spring in web.xml, configure the BlazeDS message broker as a Spring-managed bean in the application context configuration file, configured your beans, and then expose the beans as remote objects in the application context config file, then you can get started with a simple example shown below.

First, configure the DispatcherServlet to bootstrap the Spring WebApplicationContext in web.xml.  Next, you map all the /messagebroker requests to the DispatcherServlet:
<?xml version="1.0" encoding="UTF-8"?>
<web-app 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" version="2.4">

<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/web-application-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/messagebroker/*</url-pattern>
</servlet-mapping>

</web-app>
Within the web-application-config.xml, the BlazeDS message broker is first configured as a Spring-managed bean using the simple message-broker tag. This bootstraps the BlazeDS message broker. Using the message-broker tag without mapping child elements causes all incoming DispatcherServlet requests to be mapped to the MessageBroker, but you can certainly add mapping child elements for more control.

Once you're finished with the message broker, you can configure your Spring beans normally and expose the beans you want to make available for remote access using the remoting-destination tag.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:flex="http://www.springframework.org/schema/flex"
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-3.0.xsd
http://www.springframework.org/schema/flex
http://www.springframework.org/schema/flex/spring-flex-1.0.xsd">

<flex:message-broker/>

<bean id="productService" class="org.springframework.flex.samples.product.ProductDAO" >
<flex:remoting-destination />
<constructor-arg ref="dataSource" />
</bean>

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.h2.Driver" />
<property name="url" value="jdbc:h2:~/sprinflexdemodb/sprinflexdemodb" />
</bean>
</beans>
With this config, the Flex application can invoke the productService bean's public methods. The Flex application below populates a DataGrid with a list of products.  The products are acquired by remotely invoking the findAll() method of the ProductService class.
 <?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">

<fx:Declarations>
<s:RemoteObject id="ro" destination="productService"/>
</fx:Declarations>

<s:layout>
<s:VerticalLayout/>
</s:layout>
<mx:DataGrid dataProvider="{ro.findAll.lastResult}" />

<s:Button label="Get Data" click="ro.findAll()"/>

</s:Application>
This is the same code that was used to connect to a plain BlazeDS installation earlier in this article!  The client-side code and the specific server-side implementation are isolated from one another.

Spring developers can easily leverage their existing infrastructure and expose the beans to BlazeDS remoting for remote access by Flex clients.  Flex users can use the BlazeDS integration to harness the powerful features of the Spring Framework.  

For more information on other features like messaging and security integration, read Spring BlazeDS Integration Test Drive.

Comments

Peter Dstt replied on Wed, 2010/03/24 - 9:32am

Without the lazy initialization support Spring-BlazeDS is not of much use.

They keep telling they are working on it. But how long?

I think its more of management decision. BlazeDS with lazy loading support with definitely affect the sales of LCDS. I think Adobe is more worried about it, so Spring guys dont show any interest to implement it.

Please dont suggest to use third party alternatives like dpHibernate, Gilead etc. 

 

 

 

 

Kris Hofmans replied on Thu, 2010/03/25 - 9:23am

@Peter Dst: if you want lazy loading support* from the client, just like lcds with the [Managed] annotation and everything you can just start using graniteds & tide today.

There you can also integrate with more server-side technologies and everything can be configured annotation based.

 If you're doing flex/java it's definitly worth checking out: http://www.graniteds.org/

 * If you just use the hibernate externalizer you get something like dpHibernate, Gilead, if you also use Tide you get the lcds functionality.

Peter Dstt replied on Fri, 2010/03/26 - 5:33am

@Kris Hofmans

As I mentioned before why to look for alternatives. Then we have to accept the fact without lazy loading support spring-blazeds is of no use. May be its good for "Hello world" projects. You have to buy LCDS. No other go.

Its the same for Flex Builder. Even though Flex SDK is open source I bet no one could develop a project (again I am not talking about Hello world project) without the help of Flex Builder which is commercial one.

I already used GraniteDS for a Flex/EJB3 project and not so happy with it. Since there isnt any alternative I am sticking with it. Third party solutions have a lot of cons. As its a off topic I would rather not discuss about it.

Hope JavaFX comes to the limelight soon.

 

 

Francisco Tanto replied on Mon, 2011/05/16 - 12:19pm

Did you know if i can use with Flex 4.5?? i trying to conf, but i alway got this error:

 

[RPC Fault faultString="Send failed" faultCode="Client.Error.MessageSend" faultDetail="Channel.Connect.Failed error NetConnection.Call.Failed: HTTP: Failed: url: 'http://localhost:8080/WebContent/messagebroker/amf'"]
    at mx.rpc::AbstractInvoker/http://www.adobe.com/2006/flex/mx/internal::faultHandler()[E:\dev\hero_private\frameworks\projects\rpc\src\mx\rpc\AbstractInvoker.as:345]
    at mx.rpc::Responder/fault()[E:\dev\hero_private\frameworks\projects\rpc\src\mx\rpc\Responder.as:68]
    at mx.rpc::AsyncRequest/fault()[E:\dev\hero_private\frameworks\projects\rpc\src\mx\rpc\AsyncRequest.as:113]
    at mx.messaging::ChannelSet/faultPendingSends()[E:\dev\hero_private\frameworks\projects\rpc\src\mx\messaging\ChannelSet.as:1619]
    at mx.messaging::ChannelSet/channelFaultHandler()[E:\dev\hero_private\frameworks\projects\rpc\src\mx\messaging\ChannelSet.as:1209]
    at flash.events::EventDispatcher/dispatchEventFunction()
    at flash.events::EventDispatcher/dispatchEvent()
    at mx.messaging::Channel/connectFailed()[E:\dev\hero_private\frameworks\projects\rpc\src\mx\messaging\Channel.as:1117]
    at mx.messaging.channels::PollingChannel/connectFailed()[E:\dev\hero_private\frameworks\projects\rpc\src\mx\messaging\channels\PollingChannel.as:435]
    at mx.messaging.channels::AMFChannel/statusHandler()[E:\dev\hero_private\frameworks\projects\rpc\src\mx\messaging\channels\AMFChannel.as:453]

 

 

 

tks

Vaibhav Shah replied on Thu, 2011/09/15 - 10:12am

Hey, Thank you for sharing this, it was immensely helpful. I am using flex 4.5 to connect with BlazeDs(using jboss). In the server setting of my flex 4.5 application, I am cannot reference .war file that I have created via a build. It will only accept a folder. So as a work around, I am explicitly referencing the temporary war file deployed as a result of the execution of my build file. So this is the value I am using as my root folder for Flex4.5 server configuration: C:\jboss-4.2.2.GA\server\default\tmp\deploy\tmp8560368061333226812reams-reporting-exp.war The folder and the name, changes with any rebuild or restarting my jboss server: forcing me to change the server setting again. Ideally I would like to reference C:\jboss-4.2.2.GA\server\default\deploy\reams-reporting.war (win-zip file) which was created by the build.xml Any suggestions on this issue? Thank you

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.