Handling beans with BlazeDS and Flex
I recently did a little bit of testing around some concepts with BlazeDS and Flex for a game I’m writing with a friend. The game needs to be multi-player and online. Since the game will have some synchronous (real-time) and asynchronous operations going on in the same session, I needed to have an efficient way of passing data from the messaging system to the remoting system. I decided to use a bean. Creating a singleton controller, I can put whatever data I want in my bean and keep it in memory, passing it back and forth between my controllers. Here’s a small example of how to use the classes:
Messaging Section
Let’s go ahead and create an adapter class, let’s call it JavaFlexAdapter.
package com.javaflex.adapters; import java.util.logging.Logger; import com.javaflex.objects.BeanController; import flex.messaging.messages.AsyncMessage; import flex.messaging.messages.Message; import flex.messaging.services.MessageService; import flex.messaging.services.ServiceAdapter; public class JavaFlexAdapter extends ServiceAdapter { private static final Logger log = Logger.getAnonymousLogger(); @Override public Object invoke(Message arg0) { AsyncMessage message = (AsyncMessage) arg0; message.setBody("[Server] " + arg0.getBody()); // Just to say the server treated the message; BeanController instance = BeanController.getInstance(); try { instance.populateBean("value1", "value2", "value3"); } catch (Exception ex) { log.error(ex); } MessageService service = (MessageService) getDestination().getService(); service.pushMessageToClients(message, false); return null; } }
Next, comes the remoting class:
package com.javaflex.remoting; import com.javaflex.objects.BeanController; import com.javaflex.objects.MyBean; public class BeanReader { public MyBean returnBean() { BeanController instance = BeanController.getInstance(); return instance.getBean(); }
Now that we got both our Java classes that Flex talk to, let’s write the glue. This is the controller:
package com.javaflex.objects; public class BeanController { private static BeanController instance = null; private MyBean bean = null; protected BeanController() { bean = new MyBean(); } public static BeanController getInstance() { if (instance == null) { instance = new BeanController(); } return instance; } public void populateBean(String val1, String val2, String val3) { bean.setValue1(val1); bean.setValue2(val2); bean.setValue3(val3); } public MyBean getBean() { return bean; } }
And now, the bean itself:
package com.javaflex.objects; public class MyBean { private String value1; private String value2; private String value3; public String getValue1() { return value1; } public String getValue2() { return value2; } public String getValue3() { return value3; } public void setValue1(String value) { value1 = value; } public void setValue2(String value) { value2 = value; } public void setValue3(String value) { value3 = value; } }
Now that everything for the backend is written, let’s take a look at the Flex application:
<?xml version="1.0" encoding="utf-8"?> <mx:Applicataion xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="init();"> <mx:Script> <![CDATA[ import mx.rpc.events.FaultEvent; import mx.rpc.events.ResultEvent; import mx.messaging.messages.AsyncMessage; import mx.messaging.events.MessageFaultEvent; import mx.messaging.events.MessageEvent; private var consumer:Consumer = null; private var producer:Producer = null; private function init():void { consumer = new Consumer(); consumer.destination = "messaging"; consumer.addEventListener(MessageEvent.MESSAGE, msgHandler); consumer.addEventListener(MessageFaultEvent.FAULT, faultHandler); consumer.subscribe(); producer = new Producer(); producer.destination = "messaging"; producer.addEventListener(MessageFaultEvent, faultHandler); producer.send(new AsyncMessage("Test!")); } private function msgHandler(evt:MessageEvent):void { trace(evt.message); remoteObject.returnBean(); } private function faultHandler(evt:MessageFaultEvent):void { trace(evt.message); } private function roMsgHandler(evt:ResultEvent):void { trace(evt.message); } private function roFaultHandler(evt:FaultEvent):void { trace(evt.message); } ]]> </mx:Script> <mx:RemoteObject id="remoteObject" destination="remoting" result="roMsgHandler(event)" fault="roFaultHandler(event)" /> </mx:Application>
When running this code, you should get the following output:
(mx.messaging.messages::AsyncMessageExt)#0 body = "[Server] Test!" clientId = "746CE46E-AF0A-1EE4-804E-13FF83B3F9F0" correlationId = "" destination = "messaging" headers = (Object)#1 messageId = "D2713439-8507-C778-C0D5-4771D314477C" timestamp = 1263919026976 timeToLive = 0 (mx.messaging.messages::AcknowledgeMessageExt)#0 body = (Object)#1 value1 = "value1" value2 = "value2" value3 = "value3" clientId = "746CE55B-800A-EBDD-C77F-11E4902E2A4A" correlationId = "4082D4B5-8554-C76D-BD02-4771D34B5138" destination = "" headers = (Object)#2 messageId = "746CE55B-801E-822C-6CF7-92A7C01FE758" timestamp = 1263919027072 timeToLive = 0
Voilà ! You set the bean values through the messaging system, and you’re fetching the values through the remoting system.
Please let me know if this article was useful.
Thanks for reading!