Get Up and Running with BlazeDS AMF in Spring MVC

There is a dismal lack of clear instruction for configuring BlazeDS AMF services with Spring. Many of the resources that do exist refer to older versions of the software or strict scenarios that do not apply to everyone using Spring for their projects. This document will outline the steps necessary to configure BlazeDS with Spring when using both Spring MVC, specifically, and Flex.

BlazeDS can work with Spring MVC

You can grab the latest build of Spring from:
http://www.springsource.org/

You can grab the latest build of BlazeDS from:
http://opensource.adobe.com/wiki/display/blazeds/BlazeDS


First, you will want to be sure that Spring is configured in the following way:

  1. You will already have a dispatcher servlet entry in your web.xml for Spring MVC similar to the following:
    <servlet>
    <servlet-name>spring</servlet-name>
    	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    		<load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
    		<servlet-name>spring</servlet-name>
    		<url-pattern>*.do</url-pattern>
    </servlet-mapping>
  2. Be sure to include the following JAR packages in the /WEB-INF/lib directory of your project:
    • asm.jar
    • blazeds-common-3.0.jar
    • blazeds-core-3.0.jar
    • cglib-2.2.jar
    • com.springsource.edu.emory.mathcs.backport-3.0.0.jar
    • com.springsource.flex.messaging.services.remoting-3.2.0.3978.jar
    • org.springframework.flex-1.0.3.RELEASE.jar
    • commons-codec-1.3.jar
    • commons-httpclient-3.0.1.jar
    • flex-messaging-common.jar
    • flex-messaging-core.jar
    • flex-messaging-opt.jar
    • flex-messaging-proxy.jar
    • flex-messaging-remoting.jar
    • flex-rds-server.jar
    • xalan.jar
    • commons-logging.jar
    • cfgatewayadapter.jar
    • spring-flex-1.0.1.RELEASE.jar

To get BlazeDS integrated with Spring, complete the following steps:

  1. Add the following lines to web.xml:
    <servlet-mapping>
    	<servlet-name>spring</servlet-name>
    	<url-pattern>/messagebroker/amf</url-pattern>
    </servlet-mapping>
  2. Add the following lines to your servlet XML file:
    <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>
    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>
    <flex:message-broker>
    	<flex:mapping pattern="/messagebroker/amf" />
    </flex:message-broker>
  3. Create a file called “services-config.xml” and add this to /web-inf/flex:
    <?xml version="1.0" encoding="UTF-8"?>
    <services-config>
    	<services>
    		<default-channels>
    			<channel ref="my-amf" />
    		</default-channels>
    	</services>
    	<channels>
    		<channel-definition id="my-amf"
    			class="mx.messaging.channels.AMFChannel">
    			<endpointurl=http://{server.name}:{server.port}/{context.root}/messagebroker/amf class="flex.messaging.endpoints.AMFEndpoint" />
    			<properties>
    				<polling-enabled>false</polling-enabled>
    			</properties>
    		</channel-definition>
    	</channels>
    	<logging>
    		<target class="flex.messaging.log.ConsoleTarget" level="info">
    			<properties>
    				<prefix>[BlazeDS]</prefix>
    				<includeDate>false</includeDate>
    				<includeTime>false</includeTime>
    				<includeLevel>true</includeLevel>
    				<includeCategory>false</includeCategory>
    			</properties>
    			<filters>
    				<pattern>Endpoint.*</pattern>
    				<pattern>Service.*</pattern>
    				<pattern>Configuration</pattern>
    			</filters>
    		</target>
    	</logging>
    </services-config>
  4. Import the RemotingDestination class and add the following annotations to any Java classes that will be used by Flash:
    import org.springframework.flex.remoting.RemotingDestination;
    @Service("flexService")
    @RemotingDestination(value="flexService",channels={"my-amf"})
  5. If you are using Spring security, add the following line to whichever xml you are using to define security parameters so we can access message broker:
    <security:intercept-url pattern="/messagebroker/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />

Now, to get Flex talking to Java through BlazeDS, we must configure our application as such:

  1. Import the remoting event packages so that we can send data over AMF:
    import mx.rpc.events.FaultEvent;
    import mx.rpc.events.ResultEvent;
  2. Now, in your declarations tag, set up a RemoteObject structure similar to this:
    <fx:Declarations>
    		<s:RemoteObject id="ro" endpoint="http://website.root/messagebroker/amf" destination="flexService" result="resultAMF(event)" fault="faultAMF(event)">
    			<s:method name="methodNameFromJavaClass">
    				<s:arguments>
    					<arg1>{arg1}</arg1>
    					<arg2>{arg2}</arg2>
    					<arg3>{arg3}</arg3>
    				</s:arguments>
    			</s:method>
    		</s:RemoteObject>
    </fx:Declarations>

    If you are not passing any arguments, you can simplify the setup as such:

    <fx:Declarations>
    	<s:RemoteObject id="ro" endpoint=" http://website.root/messagebroker/amf" destination="flexService" result="resultAMF(event)" fault="faultAMF(event)"/>
    </fx:Declarations>
  3. Create methods to handle the result and fault events reported through our remote service:
    private function resultAMF(e:ResultEvent):void {}
    private function faultAMF(e:FaultEvent):void {}
  4. To invoke a remoting call through BlazeDS AMF, simply invoke the specific method off of our remote object instance:
    ro.methodNameFromJavaClass.send();

That should be all there is to it.

If you want to test this quickly, here is some quick MXML to do so:

<?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"
			   width="600" height="400">

	<fx:Script>
		<![CDATA[
			import mx.controls.Alert;
			import mx.rpc.events.FaultEvent;
			import mx.rpc.events.ResultEvent;

			protected function testAMF(e:MouseEvent):void {
				ro.helloWorld.send();
			}
			private function resultAMF(e:ResultEvent):void {
				Alert.show("BlazeDS Worked...", "Hot Shit!");
			}
			private function faultAMF(e:FaultEvent):void {
				Alert.show(e.fault.faultString, "Duck and Cover!!!");
			}
		]]>
	</fx:Script>

	<fx:Declarations>
		<s:RemoteObject id="ro" endpoint="http://website.root/messagebroker/amf" destination="flexService" result="resultAMF(event)" fault="faultAMF(event)"/>
	</fx:Declarations>

	<s:Button width="375" height="120" label="Test BlazeDS" click="testAMF(event)" fontSize="36" fontWeight="bold" horizontalCenter="0" verticalCenter="0"/>

</s:Application>

Special thanks to Carrie Lorenz for figuring out all the Spring MVC bits and assisting with this documentation.

Note that this document was compiled from our internal experiences integrating BlazeDS and Spring MVC. This is what worked for us… we do not claim to be experts in this area – if you have any feedback, please let us know!

Flash Remoting (AS2) in Flash CS3

I’m surprised that while any sort of remote connection classes you could want are included in the core packages of ActionScript 3.0, if you are working with ActionScript 2.0 within Flash CS3, the classes you need are still not included under a default install. I’ve lamented this fact for years as it has held true each time Macromedia/Adobe releases a new version of the IDE. There may be an excellent reason for this but I do not know what it could be.

Flash CS3 does not include the NetConnection Debugger either. I’ve found that the simplest thing to do is to use the SWC files from Flash 8 alongside the NetConnectionDebugger.swf which is launched separately. It works quite well so I’ve packaged both an FLA with the Remoting SWC components along with the NetConnectionDebugger.swf which can all be used to get around the fact that none this vital stuff is shipped along with the new authoring environment.

Remoting Components

You can also download the unpackaged classes from here.