« February 2010 | Main | April 2010 »

March 2010 Archives

March 4, 2010

Spring BlazeDS Integration

Hi to all, in this post I will explain how simple it is to configure an application that requires

- Front-end in Flex
- Back-end in Spring

with the Spring BlazeDS Integration.

To illustrate the integration support of Spring BlazeDS, I've built a sample application with:

Flex 4
Spring 2.5.6
Tomcat 6
MySql 5
Java 6

Data representation

We just represent information about Employee set. Specifically we represent the following fields:

- name
- surname
- address
- email
- category, to simplify we have supposed only 4 category : analyst – consultant – junior - manager

Architecture layers

Front-end

- Flex application that shows data on Employee set.

Back-end, ORM framework JPA

- Spring bean : EmployeeService
- DAO : EmployeeDAO
- Data : Employee

How to configurate Spring BlazeDS Integration

First of all we have to configure the MessageBroker component, core of the Spring BlazeDS Integration, because HTTP messages from the Flex client will be routed through the Spring DispatcherServlet to Spring managed MessageBroker.
Once this step is complete, we will be sure that remoting calls from the flex client reach their destination, so all we have to do is allow Spring to export its beans. To ensure this we must configure the BlazeDS Remoting service and all the necessary remote destinations.

MessageBroker's configuration

We have to configure MessageBroker into app-context.xml file

Add Flex namespace

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:flex="http://www.springframework.org/schema/flex"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/flex
http://www.springframework.org/schema/flex/spring-flex-1.0.xsd">

...
<beans>

Spring provide an XML config namespace for MessageBroker's configuration inside app-context. To use the namespace support we must add the schema location into the Spring XML configuration files. This makes the Spring BlazeDS Integration configuration tags available under the flex namespace into ours configuration files. We have to be sure to refer to the spring-flex-1.0.xsd as every element and attribute is fully documented there.

To complete MessageBroker's configuration we have to add message-broker tag :

<flex:message-broker/>

How to configurate Flex client's mapping towards MessageBroker in three simple steps

1) Definition of the DispatcherServlet in web.xml

The simple request mapping scenario is when the front-end Flex is the only client type for the application. In this case we can just map /messagebroker as top-level path for requests.

<servlet>
<servlet-name>BlazeServlet</servlet-name>
<servletclass>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param>
<param-name>contextConfigLocation</param-name>
<param-value> /WEB-INF/spring/app-context.xml </param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>BlazeServlet</servlet-name>
<url-pattern>/messagebroker/*</url-pattern>
</servlet-mapping>

2) HandlerMapping into Spring app-context.xml

We have to configure an HandlerMapping to allow the correct requests mapping towards MessageBroker, but in this case we have to do nothing, because when we use a message-broker tag, there is a bean automatically installed that allows the HandlerMapping. This bean is a SimpleUrlHandlerMapping that maps all the incoming requests from DispathcherServlet to MessageBroker through the MessageBrokerHandlerAdapter. In practice the default settings installed by <flex:message-broker/> tag regard how to include the following configuration:

<!-- Maps request paths at /* to the BlazeDS MessageBroker -->
<bean
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<value>
/*=_messageBroker
</value>
</property>
</bean>

<!-- Dispatches requests mapped to a MessageBroker -->
<bean class="org.springframework.flex.servlet.MessageBrokerHandlerAdapter"/>

So HandlerMapping configuration in the spring app-contex.xml is how to include the message-broker tag.

3) Channel definition in the BlazeDS services-config.xml

<channel-definition id="my-amf" class="mx.messaging.channels.AMFChannel">
<endpoint url="http://{server.name}:{server.port}/ {context.root}/messagebroker/amf"
class="flex.messaging.endpoints.AMFEndpoint"/>
</channel-definition>

To complete the correct requests mapping towards MessageBroker we have to define a channel to secure communication from client to server. In this way flex client can send and receive data correctly. Channel definition is in the services-config.xml file and must correspond to the chosen mapping.

Exporting Spring beans for Flex Remoting

1) Remoting Service config

To configure the BlazeDS RemotingService we have to include remoting-config.xml file in the BlazeDS configuration, but with the Spring BlazeDS Integration this configuration file can be left out completely as the inclusion of the message-broker tag in the Spring configuration will cause the RemotingService to be configured with sensible defaults if none already exists at startup time. The end result is essentially equivalent to including the following minimal remoting-config.xml in the BlazeDS configuration.

<?xml version="1.0" encoding="UTF-8"?>
<service id="remoting-service" class="flex.messaging.services.RemotingService">
<adapters>
<adapter-definition id="java-object"
class="flex.messaging.services.remoting.adapters.JavaAdapter"
default="true"/>
</adapters>
</service>

We have just set a default channel in the service-config.xml

<services>
<default-channels>
<channel ref="my-amf"/>
</default-channels>
</services>

2) Remoting destination tag

It allows to export existing Spring-managed services for direct remoting from a Flex client. Given the following Spring bean definition for a employeeService bean :

<!-- Bean employeeService -->
<bean id="employeeService" class="service.EmployeeService">
<constructor-arg ref="employeeDAO" />
</bean>

and assuming the existance of a Spring-managed MessageBroker configured via the message-broker tag, the following remoting-destination tag will expose the service for remoting to Flex client as a remote service destination called employeeService:

<!-- REMOTING DESTINATION TAG -->
<flex:remoting-destination ref="employeeService" />

We have seen that with few steps is possible to build an application that support a front-end in Flex and a back-end in Spring through the Spring BlazeDS Integration which focuses on a single main component : MessageBroker.

At this link you'll find the official Spring BlazeDS Integration reference.

March 15, 2010

AutoComplete custom component in Flex

Around the web we can find a lot of interesting e useful flex custom components. In my last works I had the chance to use the Autocomplete component developed by Hillel Coren (http://hillelcoren.com). In this post I'll try to present it briefly.


Customizing behavior and interface of the component :
This component is very similar to a standard ComboBox, although it doesn't extend from that kind of flex UIComponent. It has a fair number settings you can adjust, like:
- selectedItemsStyleName: through this property, developers can control the look of selected items. There are four choices: facebook, macMail, underline and none
- prompt: using this property you can set a string the component will display when no value is set.
- ackSpaceAction: this property determines what to do when a user press backspace. By default the component focus the item, but this can be changed to remove it.
- enableClearIcon: this boolean property, if set to true, make the component to display a little cross icon that allow users to clean the search field of the component.

Customizing drop down aspect
We can control how the item is displayed through out the component setting the labelField or the labelFunction property, like in most other Flex components. AutoComplete has two other properties we can use for customizing the drop down label:
- dropDownLabelFunction: which returns an HTML string to handle formatting the item;
- dropDownItemRenderer: if you like greater control over the layout.

Multiple selections and events
If the boolean property allowMultipleSelection is set to “true”, the component allows user to select more than one item. So the AutoComplete can contain selected items and the search string. Access to all these elements is granted by two properties:
- searchText: this property can be used to get/set the search string.
- text : this property returns a string representation of the selected items.

Related to this there are two main events which the component dispatches: change and searchChange. The change event is dispatched when the selectedItem property changes, while the searchChange event is dispatched when the search string is changed.


Filtering the data
To filter the data you can use the built-in options by setting the “matchType” property; the built-in options are:
- beginning: Only match the beginning of the string.
- word: Match the beginning of any of the words in the string.
- anyPart: Matches any part of the string.

You can also create a custom filter by setting a value for the filterFunction property.


Example Application
I used the AutoComplete component in the “search area” of an application, to supply users with a better experience in navigating data and searching information. It's also very useful in filtering collections of data ( and complex data) represented by listComponent. To demonstrate this I wrote a simple example application in which users can use the autoComplete component to filter the entries of a data grid containing information about people, represented with “name”, “last name” and an “email” address.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="horizontal"
xmlns:hc="com.hillelcoren.components.*">
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import com.hillelcoren.utils.StringUtils;
import com.hillelcoren.components.AutoComplete;

private function labelFunction(item:Object):String
{
var str:String = item["name"] +" "+item["lastname"]+ " &lt; "+item["email"]+" &gt;";
return str;
}

private function filterFunction( item:Object, searchStr:String ):Boolean
{
if (searchStr.length == 0)
{
return true;
}

var str:String = labelFunction(item);

switch (autoComplete.matchType)
{
case AutoComplete.MATCH_ANY_PART:
return StringUtils.contains( str, searchStr );
case AutoComplete.MATCH_BEGINNING:
return StringUtils.beginsWith( str, searchStr );
case AutoComplete.MATCH_WORD:
return StringUtils.anyWordBeginsWith( str, searchStr );
}
return false;
}

]]>
</mx:Script>
<mx:ArrayCollection id="dataProvider">
<mx:Array id="dataArray">
<mx:Object name="Peter" lastname="Griffin" email="p.griffin@gmail.com"/>
<mx:Object name="Mario" lastname="Brega" email="m.brega@gmail.com"/>
<mx:Object name="Homer" lastname="Simpson" email="h.simpson@yahoo.com"/>
<mx:Object name="Clark" lastname="Kent" email="c.kent@gmail.com"/>
<mx:Object name="Lex" lastname="Luthor" email="l.luthor@gmail.com"/>
<mx:Object name="Peter" lastname="Parker" email="p.parker@yahoo.com"/>
<mx:Object name="Ned" lastname="Flanders" email="n.flanders@gmail.com"/>
<mx:Object name="Lois" lastname="Lane" email="l.lane@gmail.com"/>
<mx:Object name="John" lastname="Zoidberg" email="j.zoidberg@yahoo.com"/>
</mx:Array>
</mx:ArrayCollection>



<hc:AutoComplete id="autoComplete" dataProvider="{this.dataProvider}"
width="35%"
labelFunction="labelFunction"
enableClearIcon="true"
prompt="Type in name or lastname or email"
filterFunction="filterFunction" />
<mx:Spacer width="10%"/>
<mx:DataGrid id="dataGrid" dataProvider="{this.dataProvider}"
width="40%" />

</mx:Application>

To obtain the correct behavior I customized the functions labelFunction and filterFunction. I needed to rewrite the first function to group the three fields in a single string, that is then used by the second function to filter data using the string representation of those fields. In this way users are allowed to search people in the datagrid, by name, by lastname or email, typing in the search string using one single autoComplete component.

This custom component could be very useful also in input forms, as “smart TextInput” component. Unfortunately in this context this AutoComplete component has a little lack. It has been designed to select one item (or more) from an existing collection, but not to insert new items. The allowNewValues property allows user to insert new values in the search field, but not in the collection set as dataProvider of the AutoComplete. Moreover it is not possible to write in the search text values that have as prefixes strings representing items already in the dataprovider collection. For example: it is not possible to write “Alexander” in the search text if in the data provider there is already an item represented by the string “Alex”. Trying to type-in “Alexander” will automatically select “Alex” at the fourth character.

More information available about the component can be found within its documentation: http://web.me.com/hillelcoren/Site/AutoComplete.html

March 24, 2010

First steps with Mate Flex framework

Mate (pronounced mah-teh) is a Flex framework for the MVC ( Model View Control ) Pattern. Like other frameworks, Mate addresses the common architectural concerns in Flex such as event handling, data binding, and asynchronous processing, but the most important goal is that it's only tag-based so it's very easy to use it in our Flex Applications.
Now we are going to see how Mate manages the events and the operations connected to them and how the Data results are injected into our application.

The core of the Mate framework is the EventMap tag, where we can define all the handlers of the Events, the Objects that manage Data and the View. We can create a lot of Event maps in our application and put them in every Conteiner Components, it's easy to understand that is necessary to be careful about the position where we put them (remember the Event Handlers rule) in our Application hierarchy.
Here is a simple graph of Mate's architecture:

Mate.JPG

Now we go to see how to build an EventMap component.
First of all it's necessary to include in our project the Mate swc library. After this we can create the our EventMap component like this:

<mate:EventMap>

</mate:EventMap>

We can use this tag within our application MXML, but I think it's better to create an external component, so it easy to define the functionalities of the framework, and also we are sure that the pattern MVC isn't violated.

In the EventMap tag we can insert some EventHandler tags, were we can define the attribute “type” that indicates the type of the Event that we want to handler. All the events that we want to manage inside the EventMap could be custom or created by us, but remember to built them with the parameter bubbles set to true:

package com.comtaste.controls
{
import flash.events.Event;

public class MyEvent extends Event
{
public static const CONST_MY_EVENT:String = "constMyEvent"
public function MyEvent(type:String,bubble:Boolean = true,cancelable:Boolean = false)
{
super(type,bubble,cancelable);
}
}
}

Here is a small example of EventHandler tag:

<mate:EventMap>

<mate:EventHandlers type="{MyEvent.CONST_MY_EVENT}">

</mate:EventHandlers>

</mate:EventMap>

Once the setup of our EventHandlers is complete, we can define the Objects and the Methods that retrieve or send data from/to a server. Inside the Mate Framework we have this three tags:


  • RemoteObjectInvoker

  • WebServiceObjectInvoker

  • HTTPServiceObjectInvoker


All of these tags are used to create Object instance based on, respectively, RemoteObject class, WebService Class and HttpServive class. With them we can call a method on the object created and specify the same attributes of the standard classes from mx library. In addition, you can specify the methods to call directly as tag attribute.

Inside the Mate tags above we could define the handlers for the ResultEvent and FaultEvent, as in this part of code:

<RemoteObjectInvoker destination="YourDestination"
source="path.to.your.service"
method="methodToCall"
arguments="{['argument1', 'argument2']}">

<resultHandlers>
... this list executes when server returns results ...
</resultHandlers>

<faultHandlers>
... this list executes when server returns an error ...
</faultHandlers>

</RemoteObjectInvoker>

Into the methods that manage the result of the service, we have to define the input parameters like the contents of what the service returned, and we have to do the same thing for the fault methods (in this case the event.fault).

To specify the methods that handle the results events we can use this tag:

<MethodInvoker generator="WorkerTwo" method="receiveResults" arguments="{resultObject}" />

Here we define the class that contains the method in the attribute “generator”, the method's name in the “method” attribute and the resultObject in the “arguments” attribute. The resultObject contains the data returned by our service.
For the faults handler we can use the same tag shown above but we have to insert into it the attribute “arguments”. View the code below:

arguments="{event.fault}"

in this way we can manage the fault messages returned by the service.

So we have seen how to manage the controller layer in a Flex Application, now we are going to see the Model Layer.
Mate framework gives us an MXML-based class for the injection of the data coming from our services into the View Layer: Injector class.

The Injector Class is located as a tag inside our EventMap. In it we can push the value coming from the result of the services into the property of the object in our Application Components. Remember that the visibility of the view-object by the EventMap depends on the position of this tag inside the application hierarchy.
Below you can see an example of the Injector tag:

<Injectors target="{MyView}">
<PropertyInjector targetKey="myVar" source="{MyModel}" sourceKey="modelVar" />
</Injectors>

In the Injector tag the “target” attribute indicates the target component of the injection and the “targetKey” attribute in the ProjectInjector tag indicates the attribute of the target component that must to be change. Moreover the “source” and the “sourceKey” attributes, both in the ProjectInjector tag, are respectively the Class and the value where the injection starts.

What I explained in this post is a very simple demonstration of the architectural structure of the Mate Framework. Next time I will show you a little example where we could see something more and afew best-practice rules to applicate for a correct use of this framework.

Regards

March 29, 2010

Flex WebService: how to list available operations at runtime

The Flex WebService component provides a operations property but this is set by the MXML compiler and contains only the operations listed in the tag.
If you want to access an unknown webservice and list at runtime all available operations, you can parse the WSDL xml by yourself or, more easily, use the WSDL parser of the Flex SDK.

Here a small example that I will explain later:


<mx:Script>
   <![CDATA[
      import mx.rpc.soap.LoadEvent;
      import mx.rpc.wsdl.WSDLOperation;

      protected function loadHandler(event:LoadEvent):void
      {
         if(event.wsdl) {
            for each(var op:WSDLOperation in event.wsdl.getPort().binding.portType.operations()) {
               trace(op.name);
            }
         }
      }
   ]]>
</mx:Script>

<mx:WebService load="loadHandler(event)" useProxy="false"
   wsdl="http://webservices.amazon.com/AWSECommerceService/AWSECommerceService.wsdl"/>

One of the events for the WebService component is the load event. As stated on the reference the wsdl property of the LoadEvent class contains the WSDL object of the webservice just loaded. I'm not sure if this property could be null but I prefer to add a control to avoid a null pointer exception.
Now we have a WSDL object, but this class is not included in Flex language reference, so let's take a look to its source:


[ExcludeClass]
/**
* Manages a WSDL top-level definitions element. WSDL definitions
* may contain imports to other WSDL definitions. Only SOAP bindings are
* supported.
*
* @private
*/
public class WSDL

Well, this class will neither show up in the docs nor in the Flex Builder intellisense. This could indicate that it can be not stable or it could change with any SDK update, so pay attention!
Digging in the source I found that the interesting part is in parseBinding. Here for every tag parsed a WSDLOperation is created and added

to a WSDLPortType object. This portType is stored in a WSDLBinding object that is returned by this function. The parseBinding method is called by the method itself and in the parsePort method. parsePort is called by parseService that is in getService method. You can call getService directly or through getPort.

These two methods both accept a serviceName and a portName parameter, both optional. The WSDLBinding object is stored in a WSDLPort that you can access using the getPort method.

In this way you can build a dynamic client to access every WebService without the need to know its structure in advance.

About March 2010

This page contains all entries posted to Comtaste Consulting | Enterprise RIA consulting and development in March 2010. They are listed from oldest to newest.

February 2010 is the previous archive.

April 2010 is the next archive.

Many more can be found on the main index page or by looking through the archives.

Powered by
Movable Type 3.33