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>

Recommended books:

Translations:
Português do Brasil

Related Articles

BlazeDS, Flex, Java, MySQL , , ,

11 comments


  1. Efe

    Thank you for the wonderful example!

  2. murali

    Good Explanation,,,, Thanks

  3. bola

    Hey this Tutorials as been helpful many thanks

  4. Venkat

    configuration of JBoss link leads to other than english language.. not understandable.. not helpfull for beginer’s.

    -regards.
    vm.

  5. Pingback: Leonardo França » Integrando Flex com Java usando BlazeDS – primeiros passos

  6. Pingback: Leonardo França » Adobe Flex with PHP using ZendAMF – first steps

  7. SaRaTh

    Hi,
    I am new to Adobe Flex, i am trying to execute the above example. What is the file name of the action script code? Able to deploy the .war file but nothing is displaying on the screen.

    Appriciate your help.

    Thanks,
    Sarath

  8. Sarath

    All, did anybody executed the above example. I am using eclipse plug-in for flex 4, able to deploy it properly. But i am unable to see anything on the screen getting, ‘HTTP Status 404 – /contacts’.

    Thanks in advance.
    Sarath

  9. it was very nice and detailed example.

  10. Sunilkumar

    I tried the same example what you have posted, i am not getting arraylist in flex side. it is giving java.lang.nullpointerexception, i am using flash builder4.5(with php). using blazeds>4 what may be the problem? if i send a single vo object it is coming.but problem with arraylist. can i know what may be the problem?

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>