Flex and WebServices Portlet

If you follow this blog regularly you might have noticed that i am experimenting with how to use Flex in Portlet, which seems to be getting popular option. I started by creating simple Contact table in the database and then demonstrated how you can use Flex for adding and displaying records in the table. So far i have demonstrated how to use


In this last part i am going to demonstrate how you can use the Web Service in the Portlet from Flex application. The basic idea is that the Portlet will return HTML that loads Flex object from the doView() method but once that is done, the Flex will talk directly to the Web Service which is part of Same Portlet .war file directly without going through portlet



You can download the sample code for this blog from here



First i did create a simple WebServicesContactPortlet portlet like this

public class WebServicesContactPortlet extends javax.portlet.GenericPortlet {
public void doView(RenderRequest request, RenderResponse response) throws PortletException, IOException {
System.out.println("Entering WebServicesContactPortlet.doView()");
response.setContentType(request.getResponseContentType());
getPortletContext().getRequestDispatcher("/index.jsp").include(request, response);

}
}


In this portlet i am forwarding control to index.jsp for generating markup of the view mode. The index.jsp includes WSDataExchange.swf, this is how my Flex source looks like

<?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" minWidth="955"
minHeight="600" creationComplete="initLogging()">
<fx:Script>
<![CDATA[
import com.webspherenotes.flex.Contact;
import mx.controls.Alert;
import mx.logging.LogEventLevel;
import mx.logging.targets.TraceTarget;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.rpc.soap.WebService;
import mx.utils.ObjectUtil;
private function initLogging():void {
trace("Entering initLogging");
var logTarget:TraceTarget = new TraceTarget();
logTarget.level = LogEventLevel.ALL;
contactList.getContactList.send();
trace("Exiting initLogging");
}
public function getContactList_result(event:ResultEvent):void{
trace("Inside getContactList_result");
dgEmployees.dataProvider = event.result;
trace("ContactList result" + event.result);
}
public function faultHandler(event:FaultEvent):void{
trace("Inside getContactList_fault");
}
public function addContact():void{
trace("Entering addContact")
var mycontact:Contact = new Contact();
mycontact.firstName =txtFirstName.text;
mycontact.lastName = txtLastName.text;
mycontact.email = txtEmail.text;
contactList.insertContact.send(mycontact);
contactList.getContactList.send();
}
public function insertContact_result(event:ResultEvent):void{
trace("Entering insertContact_result");
}
]]>
</fx:Script>
<fx:Declarations>
<mx:WebService id="contactList"
wsdl="http://localhost:10040/wpcert/wscontactportlet/services/ContactDAOImpl/wsdl/ContactDAOImpl.wsdl">
<mx:operation name="getContactList"
resultFormat="object"
result="getContactList_result(event);"
fault="faultHandler(event);" />
<mx:operation name="insertContact"
resultFormat="object"
result="insertContact_result(event);"
fault="faultHandler(event);" />
</mx:WebService>

</fx:Declarations>
<mx:Panel x="0" y="0" width="500" height="410" layout="absolute"
title="Simple WebService Example">
<mx:DataGrid x="10" y="174" width="460" enabled="true" editable="false"
id="dgEmployees">
<mx:columns>
<mx:DataGridColumn headerText="First Name" dataField="firstName"/>
<mx:DataGridColumn headerText="Last Name" dataField="lastName"/>
<mx:DataGridColumn headerText="Email" dataField="email"/>
</mx:columns>
</mx:DataGrid>
<mx:Button x="190" y="121" label="Add Employee" id="getPerson" click="addContact()" />
<mx:Label x="110" y="12" text="First Name"/>
<mx:TextInput x="189" y="10" id="txtFirstName" />
<mx:Label x="110" y="50" text="Last Name"/>
<mx:TextInput x="189" y="48" id="txtLastName" />
<mx:Label x="110" y="84" text="E-mail"/>
<mx:TextInput x="189" y="82" id="txtEmail" />
<mx:Label x="10" y="148" text="Employees:"/>
</mx:Panel>
</s:Application>


The mx:WebService mxml element is pointing to the ContactDAOImpl web services which is part of my portlet and the two mx:operation declare that i want to use the getContactList and insertContact operation of ContactDaoImpl web service.

On the load of the swf file it calls initLogging() and in that method i am calling contactList.getContactList.send(), this results in getContactList operation of contactList service being called and once the results of the web service is available i get control in the getContactList_result method and i am using that method to assign results of websevice as dgEmployees.dataProvider

When it comes to calling web service with complex object first i have to create object of Contact which is defined as ActionScript class like this in my code

package com.webspherenotes.flex
{
[Bindable]
[RemoteClass(alias="com.webspherenotes.flex.dao.Contact")]
public class Contact
{
private var _firstName:String;
private var _lastName:String;
private var _email:String;
public function Contact()
{
}
public function get email():String
{
return _email;
}
public function set email(value:String):void
{
_email = value;
}
public function get lastName():String
{
return _lastName;
}
public function set lastName(value:String):void
{
_lastName = value;
}
public function get firstName():String
{
return _firstName;
}
public function set firstName(value:String):void
{
_firstName = value;
}
}
}


When i call contactList.insertContact.send(mycontact);, the ActionScript takes care of converting the object of Contact class into XML and passing it as argument to insertContact

For generating WebService i did copy my ContactDaoImpl in my portlet, and used RAD's generate Web Service feature to generate a web service to expose that Java Object. This is how my WebService Contact Portlet looks like