Integrating Flex with Java using BlazeDS – first steps

Adobe Flex has become a trend when it comes to view layer between developers, analyst, managers and especially users, and can integrate with virtually any language programming. In the layer of business have a good race between Java and .NET(ok ok Java takes advantage).
For the Flex can integrate seamlessly with Java, you need a gateway(a device that works in any layer of the ISO/OSI to win "differences" between networks, manipulating and converting data). that can convert the native data types of Flex to data types native to Java and vice versa using AMF protocol..
In the following link we have the data types of Flex and its counterpart in Java:
http://livedocs.adobe.com/flex/3/html/help.html?content=data_access_4.html
The AMF(Action Message Format) is protocol with open specification, compact and tranvels in binary format, and the ActionScript 3.0, will be the AMF3 supported data type specific to AS3.
Today we have several implementations that support AMF3, we use BlazeDS as a gateway for communication in ActionScript 3 and Java.
The database named "contacts" will be used MySQL with the following structure:

SQL:
  1. CREATE TABLE `tabela` (                
  2.           `id` int(11) NOT NULL,                
  3.           `nome` varchar(30) DEFAULT NULL,      
  4.           `email` varchar(100) DEFAULT NULL,    
  5.           PRIMARY KEY  (`id`)                  
  6.         ) ENGINE=InnoDB DEFAULT CHARSET=latin1

As application server we use the JBoss Application Server and will use the Eclipse and Flex Builder for coding respectively (you can to use Eclipse for Flex and Java in same IDE).
BlazeDS comes by default witn Tomcat, but it is only container servlet. With JBoss can use later ejb3, JPA, Hibernate etc.
Download the latest version of BlazeDS this link
Having everything and properly configured, let's enconding:

  • Create a new project type "Dynamic Web Project" and name it "Contacts".
  • Select the "Target Runtime" as JBoss and "Configurations" with "Default Configuration for JBoss v4.2.
  • In "Projects Facets" does not need to change anything, just click next.
  • In "Web Module" does not need to change anything, click Finish.

Done that we can begin our coding, but we will insert into project the BlazeDS libraries, if you downloaded the bin BlazeDS, just unzip the "blazeds.war" with some winrar and copy the diretory "WEB-INF\lib" into our project in "WebContent\WEB-INF\lib", so then d the same thing with the directory "WEB-INF\flex" and the file "WEB-INF\web.xml".
Configure JBoss to start the eclipse project and add the "Contacts" to be publised automatically on start JBoss (if you have not configured yet, follow the steps in this link).
Now let's test our BlazeDS is properly configured, simply open the browser and enter the following address:

http://localhost:8080/Contatos/messagebroker/amf

if you see a blank page, it means that BlazeDS is ready to be used :D

Let our VO, create a package called "br.com.leonardofranca.vo" and create a class called "ContatosVO", your code is as follow:

JAVA:
  1. package br.com.leonardofranca.vo;
  2.  
  3. public class ContatosVO
  4. {
  5.     private int id;
  6.     private String nome;
  7.     private String email;
  8.    
  9.     public int getId()
  10.     {
  11.         return id;
  12.     }
  13.    
  14.     public void setId(int id)
  15.     {
  16.         this.id = id;
  17.     }
  18.    
  19.     public String getNome()
  20.     {
  21.         return nome;
  22.     }
  23.    
  24.     public void setNome(String nome)
  25.     {
  26.         this.nome = nome;
  27.     }
  28.    
  29.     public String getEmail()
  30.     {
  31.         return email;
  32.     }
  33.    
  34.     public void setEmail(String email)
  35.     {
  36.         this.email = email;
  37.     }
  38. }

Until now, no mystery, we have a simple object to be typed using Java. Let our main class that will do all the work.

JAVA:
  1. package br.com.leonardofranca;
  2.  
  3. import java.sql.Connection;
  4. import java.sql.DriverManager;
  5. import java.sql.ResultSet;
  6. import java.sql.SQLException;
  7. import java.sql.Statement;
  8. import java.util.ArrayList;
  9. import java.util.List;
  10.  
  11. import br.com.leonardofranca.vo.ContatosVO;
  12.  
  13. public class Contatos
  14. {
  15.     Connection conn;
  16.     Statement stm;
  17.     ResultSet rs;
  18.  
  19.     public Contatos()
  20.     {
  21.         try
  22.         {
  23.             Class.forName("com.mysql.jdbc.Driver");
  24.             conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/meubanco","root","minhasenha");
  25.             stm = conn.createStatement();
  26.         }
  27.         catch (Exception e)
  28.         {
  29.             e.printStackTrace();
  30.         }
  31.     }
  32.  
  33.     public List<ContatosVO> getData()
  34.     {
  35.         List<ContatosVO> list = new ArrayList<ContatosVO>();
  36.         try
  37.         {
  38.             rs = stm.executeQuery("SELECT id, nome, email FROM tabela");
  39.             while (rs.next())
  40.             {
  41.                 ContatosVO contatosVO = new ContatosVO();
  42.                 contatosVO.setId(rs.getInt("id"));
  43.                 contatosVO.setNome(rs.getString("nome"));
  44.                 contatosVO.setEmail(rs.getString("email"));
  45.                 list.add(contatosVO);
  46.             }
  47.         }
  48.         catch (SQLException e)
  49.         {
  50.             e.printStackTrace();
  51.         }
  52.         return list;
  53.     }
  54.    
  55.     public Boolean insertData(ContatosVO contatosVO)
  56.     {
  57.         try
  58.         {
  59.             String sql = "INSERT INTO tabela (nome, email) VALUES('"+contatosVO.getNome()+"','"+contatosVO.getEmail()+"')";
  60.             if(stm.execute(sql))
  61.             {
  62.                 return true;
  63.             }
  64.         }
  65.         catch (SQLException e)
  66.         {
  67.             e.printStackTrace();
  68.         }
  69.         return false;
  70.     }
  71.    
  72.     public Boolean deleteData(ContatosVO contatosVO)
  73.     {
  74.         try
  75.         {
  76.             stm = conn.createStatement();
  77.             String sql = "DELETE FROM tabela WHERE id = '"+contatosVO.getId()+"'";
  78.             if(stm.execute(sql))
  79.             {
  80.                 return true;
  81.             }
  82.         }
  83.         catch (SQLException e)
  84.         {
  85.             e.printStackTrace();
  86.         }
  87.         return false;
  88.     }
  89.    
  90.     public Boolean updateData(ContatosVO contatosVO)
  91.     {
  92.         try
  93.         {
  94.             stm = conn.createStatement();
  95.             String sql = "UPDATE tabela SET nome = '"+contatosVO.getNome()+"', email = '"+contatosVO.getEmail()+"' WHERE id = '"+contatosVO.getId()+"'";
  96.             if(stm.execute(sql))
  97.             {
  98.                 return true;
  99.             }
  100.         }
  101.         catch (SQLException e)
  102.         {
  103.             e.printStackTrace();
  104.         }
  105.         return false;
  106.     }
  107. }

In the constructr instantiate the class from the database, the following method is to list the data from the database, returning a List of Java that fed my DataGrid in Flex, the rest of the methods (insertm update and delete) just let me return a Boolean.

Now let the party in Flex.
We begin by VO part of Flex, note that it is necessary to put the "RemoteClass":

ACTIONSCRIPT3:
  1. package br.com.leonardofranca.vo
  2. {
  3.     [Bindable]
  4.     [RemoteClass(alias="br.com.leonardofranca.vo.ContatosVO")]
  5.     public class ContatosVO
  6.     {
  7.         public var id:uint;
  8.         public var nome:String;
  9.         public var email:String;
  10.        
  11.         public function ContatosVO()
  12.         {
  13.         }
  14.  
  15.     }
  16. }

We now implement our presentation layer, we need a form with two fields name and emai, and a DataGrid to list the email database, we still nedd three buttons, one for insert, update and delete records from database.

MXML:
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
  3. <mx:HBox x="0" y="0" width="100%" height="100%">
  4.         <mx:Panel width="338" height="389" layout="absolute">
  5.             <mx:Form x="0" y="0" width="100%" height="100%">
  6.                 <mx:FormItem label="Nome:">
  7.                     <mx:TextInput id="input_nome"/>
  8.                 </mx:FormItem>
  9.                 <mx:FormItem label="Email:">
  10.                     <mx:TextInput id="input_email"/>
  11.                 </mx:FormItem>
  12.                 <mx:FormItem>
  13.                     <mx:Button id="btnCadastrar" label="Cadastrar" />
  14.                 </mx:FormItem>
  15.                 <mx:FormItem>
  16.                     <mx:Button label="Excluir"/>
  17.                 </mx:FormItem>
  18.                 <mx:FormItem>
  19.                     <mx:Button label="Atualizar" />
  20.                 </mx:FormItem>
  21.             </mx:Form>
  22.         </mx:Panel>
  23.         <mx:DataGrid height="390" id="dg">
  24.             <mx:columns>
  25.                 <mx:DataGridColumn headerText="id" dataField="id"/>
  26.                 <mx:DataGridColumn headerText="Nome" dataField="nome"/>
  27.                 <mx:DataGridColumn headerText="Email" dataField="email"/>
  28.             </mx:columns>
  29.         </mx:DataGrid>
  30.     </mx:HBox>
  31. </mx:Application>

Usually now we would need to configure the services-config.xml for the swf know where to get the service. But do differently, i will set right in the endpoint of RemoteObject:

MXML:
  1. <mx:RemoteObject id="ro" destination="blazeds" source="br.com.leonardofranca.Contatos"  endpoint="http://localhost:8080/Contatos/messagebroker/amf">
  2.         <mx:method name="getData" result="onResult(event);" fault="onFault(event);"/>
  3.         <mx:method name="insertData" result="onResultData(event);" fault="onFault(event);"/>
  4.         <mx:method name="deleteData" result="onResultData(event);" fault="onFault(event);"/>
  5.         <mx:method name="updateData" result="onResultData(event);" fault="onFault(event);"/>
  6. </mx:RemoteObject>

And the tag method,mlet configured to call the methods in my Java class, Now just write the functions that will receive the returns of success or failure, note that i left the same method in case of failure.

ACTIONSCRIPT3:
  1. import mx.controls.Alert;
  2.             import mx.events.ListEvent;
  3.             import br.com.leonardofranca.vo.ContatosVO;
  4.             import mx.collections.ArrayCollection;
  5.             import mx.rpc.events.FaultEvent;
  6.             import mx.rpc.events.ResultEvent;
  7.            
  8.             public function init():void
  9.             {
  10.                 dg.addEventListener(ListEvent.CHANGE,selectedItems);
  11.             }
  12.            
  13.             public function onResult(re:ResultEvent):void
  14.             {
  15.                 var data:Object = re.message.body;
  16.                 dg.dataProvider = data;
  17.             }
  18.            
  19.             public function onFault(fault:FaultEvent):void
  20.             {
  21.                 trace("Code: "+fault.fault.faultCode);
  22.                 trace("Detail: "+fault.fault.faultDetail);
  23.                 trace("String: "+fault.fault.faultString);
  24.             }
  25.            
  26.             public function insertData():void
  27.             {
  28.                 var contatosVO:ContatosVO = new ContatosVO();
  29.                 contatosVO.nome = input_nome.text;
  30.                 contatosVO.email = input_email.text;
  31.                 ro.insertData(contatosVO);
  32.             }
  33.            
  34.             public function onResultData(re:ResultEvent):void
  35.             {
  36.                 ro.getData();
  37.             }
  38.            
  39.             public function deleteData():void
  40.             {
  41.                 if(dg.selectedItem != null)
  42.                 {
  43.                     var contatosVO:ContatosVO = new ContatosVO();
  44.                     contatosVO.id = dg.selectedItem.id;
  45.                     ro.deleteData(contatosVO);
  46.                 }
  47.                 else
  48.                 {
  49.                     Alert.show("Selecione um item da tabela!!!");
  50.                 }
  51.             }
  52.            
  53.             public function selectedItems(evt:ListEvent):void
  54.             {
  55.                 input_nome.text = dg.selectedItem.nome;
  56.                 input_email.text = dg.selectedItem.email;
  57.             }
  58.            
  59.             public function updateData():void
  60.             {
  61.                 if(dg.selectedItem != null)
  62.                 {
  63.                     var contatosVO:ContatosVO = new ContatosVO();
  64.                     contatosVO.id = dg.selectedItem.id;
  65.                     contatosVO.nome = input_nome.text;
  66.                     contatosVO.email = input_email.text;
  67.                     ro.updateData(contatosVO);
  68.                 }
  69.                 else
  70.                 {
  71.                     Alert.show("Selecione um item da tabela!!!");
  72.                 }
  73.             }

Following the complete code:

MXML:
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="ro.getData();init();">
  3.     <mx : Script>
  4.         <![CDATA[
  5.             import mx.controls.Alert;
  6.             import mx.events.ListEvent;
  7.             import br.com.leonardofranca.vo.ContatosVO;
  8.             import mx.collections.ArrayCollection;
  9.             import mx.rpc.events.FaultEvent;
  10.             import mx.utils.ObjectUtil;
  11.             import mx.rpc.events.ResultEvent;
  12.            
  13.             public function init():void
  14.             {
  15.                 dg.addEventListener(ListEvent.CHANGE,selectedItems);
  16.             }
  17.            
  18.             public function onResult(re:ResultEvent):void
  19.             {
  20.                 var data:Object = re.message.body;
  21.                 dg.dataProvider = data;
  22.             }
  23.            
  24.             public function onFault(fault:FaultEvent):void
  25.             {
  26.                 trace("Code: "+fault.fault.faultCode);
  27.                 trace("Detail: "+fault.fault.faultDetail);
  28.                 trace("String: "+fault.fault.faultString);
  29.             }
  30.            
  31.             public function insertData():void
  32.             {
  33.                 var contatosVO:ContatosVO = new ContatosVO();
  34.                 contatosVO.nome = input_nome.text;
  35.                 contatosVO.email = input_email.text;
  36.                 ro.insertData(contatosVO);
  37.             }
  38.            
  39.             public function onResultData(re:ResultEvent):void
  40.             {
  41.                 ro.getData();
  42.             }
  43.            
  44.             public function deleteData():void
  45.             {
  46.                 if(dg.selectedItem != null)
  47.                 {
  48.                     var contatosVO:ContatosVO = new ContatosVO();
  49.                     contatosVO.id = dg.selectedItem.id;
  50.                     ro.deleteData(contatosVO);
  51.                 }
  52.                 else
  53.                 {
  54.                     Alert.show("Selecione um item da tabela!!!");
  55.                 }
  56.             }
  57.            
  58.             public function selectedItems(evt:ListEvent):void
  59.             {
  60.                 input_nome.text = dg.selectedItem.nome;
  61.                 input_email.text = dg.selectedItem.email;
  62.             }
  63.            
  64.             public function updateData():void
  65.             {
  66.                 if(dg.selectedItem != null)
  67.                 {
  68.                     var contatosVO:ContatosVO = new ContatosVO();
  69.                     contatosVO.id = dg.selectedItem.id;
  70.                     contatosVO.nome = input_nome.text;
  71.                     contatosVO.email = input_email.text;
  72.                     ro.updateData(contatosVO);
  73.                 }
  74.                 else
  75.                 {
  76.                     Alert.show("Selecione um item da tabela!!!");
  77.                 }
  78.             }
  79.         ]]>
  80.     </mx:Script>
  81.     <mx:RemoteObject id="ro" destination="blazeds" source="br.com.leonardofranca.Contatos"  endpoint="http://localhost:8080/Contatos/messagebroker/amf">
  82.         <mx : method name="getData" result="onResult(event);" fault="onFault(event);"/>
  83.         <mx:method name="insertData" result="onResultData(event);" fault="onFault(event);"/>
  84.         <mx:method name="deleteData" result="onResultData(event);" fault="onFault(event);"/>
  85.         <mx:method name="updateData" result="onResultData(event);" fault="onFault(event);"/>
  86.     </mx:RemoteObject>
  87.     <mx:HBox x="0" y="0" width="100%" height="100%">
  88.         <mx:Panel width="338" height="389" layout="absolute">
  89.             <mx:Form x="0" y="0" width="100%" height="100%">
  90.                 <mx:FormItem label="Nome:">
  91.                     <mx:TextInput id="input_nome"/>
  92.                 </mx:FormItem>
  93.                 <mx:FormItem label="Email:">
  94.                     <mx:TextInput id="input_email"/>
  95.                 </mx:FormItem>
  96.                 <mx:FormItem>
  97.                     <mx:Button id="btnCadastrar" label="Cadastrar" click="insertData();"/>
  98.                 </mx:FormItem>
  99.                 <mx:FormItem>
  100.                     <mx:Button label="Excluir" click="deleteData();"/>
  101.                 </mx:FormItem>
  102.                 <mx:FormItem>
  103.                     <mx:Button label="Atualizar" click="updateData();"/>
  104.                 </mx:FormItem>
  105.             </mx:Form>
  106.         </mx:Panel>
  107.         <mx:DataGrid height="390" id="dg">
  108.             <mx:columns>
  109.                 <mx:DataGridColumn headerText="id" dataField="id"/>
  110.                 <mx:DataGridColumn headerText="Nome" dataField="nome"/>
  111.                 <mx:DataGridColumn headerText="Email" dataField="email"/>
  112.             </mx:columns>
  113.         </mx:DataGrid>
  114.     </mx:HBox>
  115. </mx:Application>

If you got this far ok! everything right and working, but you can forget, i will go show a better and efficient to integrate Flex with Java ;)

[UPDATE]
I forgot to mention that you need a directory of the project in eclipses, called "WebContent/WEB-INF/flex" to be included in the files: services-config.xml, remoting-config.xml, proxy-config.xml, messaging-config. xml. the project is only necessary that the remoting-config.xml, whose content should be like the code below

XML:
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <service id="remoting-service"
  3.    class="flex.messaging.services.RemotingService">
  4.  
  5.     <adapters>
  6.         <adapter-definition id="java-object" class="flex.messaging.services.remoting.adapters.JavaAdapter" default="true"/>
  7.     </adapters>
  8.  
  9.     <default-channels>
  10.         <channel ref="my-amf"/>
  11.     </default-channels>
  12.    
  13.     <destination id="blazeds">  
  14.           <properties>  
  15.              <source>br.com.leonardofranca.Contatos</source>
  16.              <scope>session</scope>
  17.            </properties>
  18.      </destination>  
  19. </service>

Translations:
Português do Brasil

3 Comments

  • By Efe, October 29, 2009 @ 5:51 pm

    Thank you for the wonderful example!

  • By murali, December 17, 2009 @ 5:47 am

    Good Explanation,,,, Thanks

  • By bola, February 27, 2010 @ 10:24 pm

    Hey this Tutorials as been helpful many thanks

Other Links to this Post

RSS feed for comments on this post. TrackBack URI

Leave a comment

WordPress Themes


Video & Audio Comments are proudly powered by Riffly