Data Services with Server-Side Validation

Out of the box, Flex provides a set of great validators for client-side validation of form input (e.g. for phone numbers), but for instances in which we need to involve the server, things become a bit trickier. Before we get into the how though, a quick discussion of the why. There are numerous situations in which server-side validation is not only nice, but a must. Consider an application that asks users to register themselves. The application might ask the user to create a username, but that username must be unique. We don’t want to send our entire list of username to the client, so instead we’ll utilize validation code on the server. In a previous post, I detailed my approach for server-side validation.

In general, the design follows a similar pattern to Rails – we store a map of errors in an object within the model object itself. Persistent classes that implements the Validateable interface can be validated by our framework and an instance of ValidateableErrors will be injected into the object with a map of validation errors. If the validation framework encounters an error, it halts execution and sends the invalid object (with errors) back to the client.

Once Flex receives the updated object, the application needs to be able to display those errors. To do this, we’ll utilize a custom implementation of the mx.validators.Validator class. Before we dig into the validator class, let’s take a quick look at the ActionScript implementation of the ValidateableErrors class:

    [Bindable]
    public class ValidateableErrors
    {
        private var _errors : Object;

        public function ValidateableErrors(errors : Object) : void
        {
            this._errors = errors;
        }

        public function getFieldErrors(field : String) : Array
        {
            return this._errors[field] == null ?
                [] : [ this.createValidationResult(this._errors[field]) ];
        }

        private function createValidationResult(msg : String) : ValidationResult
        {
            return new ValidationResult(true, "", "SERVER_ERROR", msg);
        }
    }

The first thing to note is that instead of using a Dictionary, we are in fact just using a plain old object as this is how LCDS deserializes Java Maps on the Flex side. Each of the keys in the map are now properties for this object. We can this utilize the “[]” notation to retrieve the value of a given property. The validation message is wrapped in a ValidationResult object, which is utilized by the validator to display error messages in the UI.

Let’s now take a quick look at the validator implementation:

    public class ServerErrorValidator extends Validator
    {
        private var _errors : ValidateableErrors;
        public var field : String;

        public function ServerErrorValidator()
        {
            this._errors = null;
            super();
        }

        public function set errors(errors : ValidateableErrors) : void
        {
            this._errors = errors;
            validate();
        }

        override protected function doValidation(value : Object) : Array
        {
            return this._errors.getFieldErrors(this.field);
        }
    }

Our validator simply accesses the ValidateableErrors object referenced by the “errors” property for a given field. It then displays the error message via the return ValidationResult object. We can make this a clearer by looking at an example:

    <validation:ServerErrorValidator id="firstNameValidator" field="firstName"
        errors="{ this._user.validationErrors }" listener="{ this.firstName }"/>
    <validation:ServerErrorValidator id="lastNameValidator" field="lastName"
        errors="{ this._user.validationErrors }" listener="{ this.lastName }"/>

    <mx:Label x="10" y="10" text="User Validation Test" fontSize="16" color="#FFFFFF" fontWeight="bold"/>
    <mx:Panel x="10" y="42" width="480" height="200" layout="absolute" title="Create User">
        <mx:Label x="10" y="10" text="First Name:"/>
        <mx:Label x="10" y="36" text="Last Name:"/>
        <mx:TextInput x="127" y="8" id="firstName"/>
        <mx:TextInput x="127" y="34" id="lastName"/>
        <mx:Button x="385" y="128" label="Create" click="createUser()"/>
    </mx:Panel>

The User instance (“_user“) is defined elsewhere. Although not ideal, we do need to instantiate one validator per field even though we only reference a single object. The response from the data service’s “createItem” method is an updated version of the user object with the associated validation errors. Flex takes care of updating the UI appropriately to display the errors.

This implementation has worked well thus far for my purposes; however, I do see room for improvement in displaying multiple errors messages per field and in making the solution as a whole more flexible. I do welcome feedback.


Aspect Oriented Validation in Java

This will be the first of a two part series that discusses my approach towards validation in a data service application. The first part (this post) will cover the server-side aspects of the validation framework and the second (coming soon, I hope) will detail how validation information is shared with the Flex application.

In designing the validation component, I wanted the following:

  1. Little to no impact on business logic (e.g. no validation code inline with business logic)
  2. Minimal configuration
  3. Able to send validation errors to Flex client

The first design principal lends itself to aspect oriented programming, which enables us to handle “cross-cutting” concerns (see my previous post for more details). In short, we’ll be implementing a “Validator” class (an aspect) that is called upon to validate persistent objects whenever a create or update method is called in the data access layer. For this application, I have used Spring with @AspectJ annotations to build AOP components and have previously documented details on the AOP configuration for the Validator.

For the most part, the Validator class is fairly straightforward, with the exception of it being Spring application context aware (e.g. it has access to our Spring configuration). By making the Validator context aware, we can configure validation beans via Spring and dynamically load them as needed.

    @Aspect
    public final class Validator implements ApplicationContextAware
    {
        private ApplicationContext appContext;

        @Around("iamjosh.samples.util.SystemArchitecture.onCreateOrUpdate()"
            + " && args(validateable)")
        public void validate(ProceedingJoinPoint called, Validateable validateable) throws Throwable
        {
            // returns simple name, e.g. "user"
            String beanType = validateable.getSimpleName();

            // try to load a validator bean for this object
            org.springframework.validation.Validator validator
                    = this.loadValidatorBean(beanType);
            // if we didn't get a validator back, stop trying to validate
            if (validator == null) return;

            // run the validation
            ValidateableErrors errors =
                new ValidateableErrors(validateable, beanType);
            validator.validate(validateable, errors);

            // check the result of the validation -- if there are errors, assign
            // them to the validateable object
            if (errors.hasErrors())
                validateable.setErrors(errors);
            else
                // proceed if valid, be sure to pass the validateable on
                called.proceed(new Object[] { validateable });
        }

        // need to implement this method to be application context aware
        public void setApplicationContext(ApplicationContext applicationcontext) throws BeansException
        {
            this.appContext = applicationcontext;
        }

        private org.springframework.validation.Validator loadValidatorBean(String validateableBeanName)
        {
            String validatorBeanName = validateableBeanName + "Validateable";
            org.springframework.validation.Validator validator = null;
            try
            {
                validator =
                    (org.springframework.validation.Validator)this.appContext.getBean(validatorBeanName);
            }
            catch(NoSuchBeanDefinitionException nsbde) { // do something }
            catch(BeansException be) { // do something }
            return validator;
        }
    }

In this case, I am favoring the idea of convention over configuration. The naming convention for my validator beans should be “modelClassNameValidator” or “userValidator” for the User class. This keeps things simple. In the future, I plan to add an option to override this default.

I won’t go into the details of the ValidateableErrors class, but it is just a wrapper around Spring’s BindingResult class that defers all method calls and adds a few others. For those familiar with Rails, this class and its relationship to the model are very similar to the Errors class in ActiveRecord classes. Each validateable model class has an “errors” property that references a ValidateableErrors object – this is what is eventually passed to Flex (more on this in a future post).

Any persistent model that is to be validated by our validation framework must implement the Validateable interface and extend the BaseValidateable abstract class.

Finally, a quick discussion of how the validation rules are defined. I wanted to avoid mixing validation code with business logic and partially achieved this by utilizing AOP to call my validation framework. But I also wanted to avoid defining validation rules in code as this can be become cumbersome and create extraneous classes. To that end, I chose to utilize the Valang validation language, which is part of the Spring Modules library, a set of extension to Spring. Details on Valang can be found in the references below, but it allows us to write succinct validation rules as part of the Spring configuration. For the user class our Valang code looks like this:

    <bean id="userValidator" class="org.springmodules.validation.valang.ValangValidator">
        <property name="valang">
            <value>
                <![CDATA[
                    { firstName : ? is not blank : 'First name is blank' : 'first_name_empty' }
                    { firstName : length(?) < 30 : 'First name too long' : 'first_name_length' : 30}
                    { lastName  : ? is not blank : 'Last name is blank' : 'last_name_empty' }
                    { lastName  : length(?) < 50 : 'Last name too long' : 'last_name_length' : 50 }
                    { email     : ? is not blank : 'E-mail is blank' : 'email_empty' }
                    { email     : email(?) == false : 'E-mail is invalid' : 'email_invalid' }
                    { email     : ? is blank or length(?) > 3 : 'E-mail is too short' : 'email_to_short' }
                ]]>
            </value>
        </property>
    </bean>

By naming the validation bean “userValidator” the validation framework will automatically identify this bean as the validation bean for the User class. We can then apply whatever Valang rules are deemed necessary by our requirements to implement server-side validation. Any errors are then inserted into the Validateable object as a ValidateableErrors object that will be sent back to Flex.

References


Adobe Open Sourcing LiveCycle Data Services as BlazeDS

One of the downsides for LCDS development for me has been the lack of folks out there who have worked with the technology and that it is only available for Java backends (unless you use third party technology). Now, Adobe has announced that it will be open sourcing LCDS under the name “BlazeDS,” with a beta version available now on the Adobe Labs site. This is very exciting news as it will open the messaging and remoting framework that we use for Java to other platforms and will probably increase the pool of developers using it.

Adobe is also publishing the Action Message Format (AMF) protocol specification. According to Adobe, delivery of messages via AMF is up to ten times faster than with XML as it is already in a machine readable format (binary) and does not need to be translated, as is the case with XML.

Of note, however, is that the data management services component (which is what I have primarily been using) will still only be available as part of LCDS, which will also include new technologies around offline data synchronization in the future.

This is extremely exciting news for those of us working with LCDS…I mean BlazeDS.

References


Serialization of Custom Collections for Flex Data Services

In my current project, we have a custom collection on the Java side that is supposed to be sent via LCDS to the Flex client. When we began testing, however, we found that the collection was not being passed, only the properties of “standard” Java types were (e.g. String, int). It seems that if LCDS does not know how to handle an object, it simply ignores it and does not include it in the serialization process. This was the case here, LCDS did not understand how to serialize our custom collection and simply did not include it in the transfer.

For example, in the model code below, when an instance of MyListKeeper is serialized and sent to the Flex client, only the name property is included, not myList.

     public class CustomList
         extends ArrayList<Foo>
         implements List<Foo>, Serializable
     {
         // constructors
         // extension methods, e.g.
         public Bar getFirstBar() { ... }
     }

     public class MyListKeeper
         implements Serializable
     {
         private CustomList myList;
         private String name;

         // getters & setters
     }

We were able to solve this by writing custom serialization methods (via the java.io.Externalizable interface) for both the collection and the class that contains a reference to it. In the code below, notice that our classes now implement Externalizable (a subclass of Serializable).

     public class CustomList
         extends ArrayList<Foo>
         implements List<Foo>, Externalizable
     {
         // as in the previous example ...

         public void writeExternal(ObjectOutput out)
             throws IOException
         {
             // externalizes the list - LCDS knows how to handle an ArrayList
             out.writeObject(new ArrayList(this));
         }

         public void readExternal(ObjectInput in)
             throws IOException, ClassNotFoundException
         {
             // start by clearing the current collection
             this.clear();
             // now read in the new list and store it
             this.addAll((List)in.readObject());
         }
     }

     public class MyListKeeper
         implements Externalizable
     {
         // as in the previous example ...

         public void writeExternal(ObjectOutput out)
             throws IOException
         {
             out.writeUTF(this.name);
             out.writeObject(this.myList);
         }

         public void readExternal(ObjectInput in)
             throws IOException, ClassNotFoundException
         {
             this.name  = in.readUTF();
             // the following may not be 100% correct, feel free to correct me
             this.myList = (CustomList)this.readObject();
         }
     }

Finally, we need to mirror our custom serialization on the Flex side. In ActionScript, classes with custom serialization implement the flash.utils.IExternalizable interface.

    [Managed]
    [RemoteClass(alias="CustomList")]
    public class CustomList
        implements IExternalizable
    {
        public var list : IList;

        // other methods, etc

        public function readExternal(input : IDataInput) : void
        {
            this.list = ArrayCollection(input.readObject());
        }

        public function writeExternal(output : IDataOutput) : void
        {
            output.writeObject(this.list);
        }
    }

    [Managed]
    [RemoteClass(alias="MyListKeeper")]
    public class MyListKeeper
        implements IExternalizable
    {
        public var myList : CustomList;
        public var name : String;

        // other methods, etc

        public function readExternal(input : IDataInput) : void
        {
            this.name = input.readUTF();
            // the list itself is received as an ArrayCollection, so we just assign it directly
            this.myList.list = input.readObject();
        }

        public function writeExternal(output : IDataOutput) : void
        {
            output.writeUTF(this.name);
            output.writeObject(this.myList);
        }
    }

Adobe has a nice overview of custom serialization as well, but focuses primarily on utilizing it to control which parameters are serialized.

References


A Change to iBatis

In my previous post, I covered how to build a small LCDS application that utilizes Spring and Hibernate on the backend. This application was very simple and limited, but I was able to easily apply the same principles to a more complex project at work.

Following the design pattern I typically follow, I started by designing the data model (I guess I am a bit bias towards how Rails does things, but in general, I feel this is a better pattern for designing applications). The data model was slightly more complex than my sample in that it would require a couple of joins to support my model classes appropriately. I felt this was simple enough, the SQL is.

Hibernate seemed to disagree though. It became very difficult to map my data model to my model classes and if I wanted to follow my designed data model, I would be forced to change the semantics of the model layer. I also ran into difficult in persisting a custom collection, but was able to solve that (will try to post details soon). In the end it all just became to much. Hibernate is great, if you do things the way it does things – I evidently do not.

A colleague recommended that I check out iBatis as an alternative to Hibernate. When using iBatis, the developer is responsible for creating the SQL called by the application and defining the relationship between query results and model properties. Hibernate, on the other hand, requires a mapping from the database schema to the model classes and generates SQL on its own. You could say that there is some degree of “magic” to Hibernate.

Utilizing the same architectural pattern I followed in my sample application, I was able to quickly replace Hibernate-backed implementations of my DAO classes with iBatis ones. Spring also provides integration with iBatis, so bringing it into the application was very straightforward.

In the end, I was a bit disappointed to have to pull out Hibernate, but there were just to many challenges on to short of a schedule.


Building a LiveCycle Data Service Application with Spring and Hibernate

In order to gain a better understanding of Flex and data services with Java, I decided to build a simple order management application that demonstrates a number of capabilities. The application will be responsible for managing orders and the items in them. The UI itself is extremely simplistic and the use case for the application is very limited:

Flex Order Manager UI

For the rest of this article, I am going to focus primarily on the data services aspect of the application and how it is wired up from end-to-end. I do plan to cover other aspects of my sample application, particularly my lessons learned around Hibernate, in future posts though.

Download Sample Code (zip)

Data Model

To get started, we’ll take a quick look at the data model for the application. There are three data elements that we will deal with: (1) orders, (2) products, and (3) line items. An order contains one or more line items, each of which is associated with a single order.

Data Model Diagram

Data Service Application

When I initially started learning about Flex and data services, I found it difficult to understand exactly how LCDS integrated with my application. In the end LCDS is actually part of the web application – if you follow along with my earlier post on generating an LCDS application skeleton, you’ll find that the LCDS libraries are included in the WAR file.

In the end, LCDS acts as the controller for the application. It provides a set of servlets for receiving, sending, and interpreting messages in various formats. The web application’s descriptor file (web.xml) defines these servlets as endpoints in the application. On the Flex side, the services_config.xml file identifies these endpoints to the Flex application. For more details, I recommend reviewing the default versions of these files included in your LCDS distribution (although this does require some knowledge of web application configuration). Although there are other options, I have chosen to use Adobe’s Action Message Format (AMF) for communication.

LCDS Architecture

With the controller (LCDS) and view (Flex) layers of my application complete, I turned to the model layer. I decided to use Hibernate to provide object-relational mapping and data persistence and Spring to manage transactions and the Hibernate session factory (primarily to make my life easier). There are numerous references online that discuss integrating Spring and Hibernate as well as information on utilizing the power of these tools for a Flex data service. In the end, the model layer of my application flows as follows:

Flow Diagram

Beans

With our order management application service designed, we can start to work on building its various pieces. LCDS, Spring, and Hibernate handle much of the heavy lifting here, but we need to fill in a few gaps in the BO, DAO, and bean layers.

Being the simplest, I started by building the three Java beans that my application requires along with the associated ActionScript models (they are very similar).

There are a couple of key points to notice:

  • For each property in the Java bean, there is an associated public attribute in the ActionScript class (of the same name!). This allows LCDs to serialize and deserialize objects properly.
  • In the ActionScript class, I have included two metadata tags:
    • [Managed] – provides utility methods for objects managed by a data service
    • [RemoteClass(alias="iamjosh.samples.lcds.models.Order")] – maps this class directly to a remote Java class
  • One other items of note, particularly for the LineItem class, are the equals() and hashCode() method. These are extremely important for Hibernate, so much so that I will review them in a future post.

Flex-Spring Integration

Since Spring wil be managing Hibernate, we only need to wire Spring to Flex. Luckily, Christophe Coenraets provides detailed information of how to do so. Like Christophe, we will be utilizing Jeff Vroom’s SpringFactory to provide Flex with initialized instances of Spring beans. All we need to do is include the SpringFactory class (avaiable on Adobe Exchange), register it in services-config.xml, and install the Spring libraries.

WEB-INF/flex/services-config.xml – register the SpringFactory with Flex

<factories>
    <factory id="spring" class="iamjosh.samples.lcds.factories.SpringFactory"/>
</factories>

WEB-INF/web.xml – include Spring configuration in the web application

<!-- Application context configuration for Spring -->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<!-- listener for Spring -->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

From the Spring framework, there are two JAR files that need to be included in the application: (1) spring.jar and (2) spring-hibernate3.jar. The latter provides integration between Spring and Hibernate.

Flex Data Assembler

When a request is made from the client (Flex) side, they are sent to an object called an assembler. We will need to create a custom assembler class to provide the interface from the data service to our business layer (BO) or data access layer (DAO). The assembler class extends the flex.data.assemblers.AbstractAssembler abstract class. The custom assembler is responsible for providing a set of callback methods (essentially get, update, create, and delete) that can be invoked from the client application (actually, in the Flex application, you’ll see that we call these methods “directly”).

Once we have created this class, we need to wire it to a destination that can will be referenced by the Flex application:

WEB-INF/flex/data-management-config.xml

<destination id="order.spring">
    <adapter ref="java-dao"/>
        <properties>
            <source>orderAssemblerBean</source>
            <factory>spring</factory>
            <metadata>
                <identity property="id"/>
            </metadata>
        </properties>
        <channels>
            <channel ref="my-rtmp"/>
        </channels>
</destination>

The above XML essentially maps a destination (order.spring) to an assembler (orderAssemblerBean), which is contructed by the Spring factory.

The configuration to map the order assembler to an actual implementation is handled in the Spring configuration (WEB-INF/applicationContext.xml). We also point to a business object that is utilized by the assembler class here.

<bean id="orderAssemblerBean" class="iamjosh.samples.lcds.assemblers.OrderAssembler">
    <property name="orderDAO" ref="orderDAOBean"/>
</bean>

Spring-Hibernate Integration

The final step is to integrate Spring and Hibernate by configuring the Hibernate session factory that the DAO class will utilize (once again in applicationContext.xml):

<bean id="orderDAOBean" class="iamjosh.samples.lcds.dao.OrderDAOImpl">
    <property name="sessionFactory" ref="sessionFactory"/>
</bean>

Our DAO implementation (OrderDAOImpl) is responsible for making calls to the database via the Hibernate package. You will also need to download and include the hibernate3 library as well.

Accessing the Data Service from Flex

The last step in building our sample application is to call the data service from the Flex application. I chose to use the DataService object to do so:

<mx:DataService id="orderService" destination="order.spring" autoCommit="true" />
<mx:ArrayCollection id="_orders"/>

<mx:Script>
    <![CDATA[
        private function onCreationComplete() : void
        {
            // call the method we want from the OrderAssembler (our service)
            this.orderService.fill(this._orders);
        }
    ]]>
</mx:Script>

As you can see above, we are referencing the data service destination defined in data-management-config.xml and the fill() method, one of the four standard methods provided by a data service. The fill() method is defined in the OrderAssembler. Other methods in the Assembler (e.g. createItem) can also be called in the same manner (orderService.createItem(newItem)).

Final Thoughts

Of course there is a great deal more depth to this subject than I am able to cover here, but my goal was to document how I built a basic working LCDS application and bring together information that I found in a number of different sources.

References


Debugging LCDS in Eclipse

I found a very helpful tidbit this afternoon…how to via AMF traffic as part of your debug logging stream. In the WEB-INF/flex/services-config.xml file, change “Error” to “Debug” in the following line:

    <logging>
        <target class="flex.messaging.log.ConsoleTarget" level="Debug">
        …
    </logging>

After restarting your application, you should see the console fill with output such as:

15:06:11,652 INFO  [STDOUT] [Flex] Deserializing AMF/RTMP request
Version: 0
  (Command method=connect (2) trxId=1.0)
    (Object #0)
      app = ""
      flashVer = "WIN 9,0,60,235"
      swfUrl = "http://localhost:8080/LCDS-Sample/bin/Main.swf"
      tcUrl = "rtmp://localhost:2038"
      fpad = false
      capabilities = 15.0
      audioCodecs = 1639.0
      videoCodecs = 252.0
      videoFunction = 1.0
      pageUrl = "http://localhost:8080/LCDS-Sample/bin/Main.html"
      objectEncoding = 3.0
    false
    "nil"

References: