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.

Advertisements

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


Passing Arguments to Advice in Spring with @AspectJ Support

In building an aspect-oriented validation framework, I encountered the need for passing arguments to my advice methods. Not being an AOP expert, I found numerous methods via Google for doing this in Spring. Unfortunately, none of them worked. I ran into error messages along the lines of “wrong number of arguments” and something about formal parameters. I eventually created the following solution (note that pointcuts are defined in a single class called “SystemArchitecture”):

    package iamjosh.samples.util;

    @Aspect
    public class SystemArchitecture
    {
        // pointcuts that are called when a "create" or "update" method is called in the service package
        @Pointcut("onCreate() || onUpdate()")
        public void onCreate() {}

        @Pointcut("execution(* iamjosh.samples.service..*.create(..))")
        public void onCreate() {}

        @Pointcut("execution(* iamjosh.samples.service..*.update(..))")
        public void onUpdate() {}
    }

And now the advice:

    package iamjosh.samples.validation;

    @Aspect
    public class Validator
    {
        @Around("iamjosh.samples.util.SystemArchitecture.onCreateOrUpdate()"
            + " && args(validateable)")
        public void validate(ProceedingJoinPoint called, Validateable validateable)
            throws Throwable
        {
            // do whatever here
        }
    }

Two things of note in the above example:

  • Around advice is used here so that execution can be halted if the validateable object is found to be invalid, but this method will apply to any type of advice.
  • Only classes implementing the Validateable interface can be passed into the create() and update() methods in my application. The parameter in “args” that defines the advice references the name of the argument, not its type.

Like I said in the opening, I found a number of different methods that claimed to accomplish this same task, but this was the one I found to be most effective. The one change I would like to make is to define the argument type (here, “Validateable”) as part of the pointcut itself instead of with the advice, but no luck so far. Please feel free to comment with enhancements.


Aspect Oriented Error Handling in Java

Over the past few days I’ve been building out several application architecture components to support our Flex data service application. My goal was to make these components as unobtrusive as possible in the core code, primarily because it allows our developers to focus on business logic instead of peripheral concerns. That goal led me to look at Aspect Oriented Programming (AOP).In short, AOP handles “cross-cutting concerns” or modules that span multiple parts of the system. Logging errors is an example of a cross-cutting concern, because all classes that might throw an exception require such a service. A much deeper explanation of AOP can be found on Wikipedia. I am by no means an AOP expert, but I felt that detailing my approach might be of value to others.

To get started, we need a library that will enable us to build AOP components. I selected the Spring Framework because we are already using Spring in our application and it provides good support for AOP. The latest version of Spring (2.5) also includes integration with AspectJ to be more expressive and offer a simpler programming model than past versions of Spring. It allows us to define aspects, point cuts, etc. via a combination of XML/annotations and code.

Using the annotation approach, we can use regular Java classes to create aspects. In our case, the ErrorHandler class is an aspect that defines its join point into the application. A “join point” is a point of execution in software, for example, when an exception is thrown. The after-throwing join point to identify application code or “advice” that should be run after an exception is thrown:

    @Aspect
    public final class ErrorHandler
    {
        @AfterThrowing(
            pointcut="within(iamjosh.samples..*)",
            throwing="exception"
        )
        public void processError(JoinPoint logged, RuntimeException exception)
        {
            // log the error message via the logging component
        }
    }

The annotations in this class do two things: (1) define this class as an aspect (or cross-cutting module) and (2) indicate its join point (or where and how it is called). In this case, we call the “processError” method after an exception is thrown.

The other key here is the “pointcut.” The pointcut defines where a join point should be run; any join point that matches the pointcut will cause the advice to be run. In our example, the advice (the processError method) will be run after an execption is thrown (the join point) anywhere in the “iamjosh.samples” package and its descendants (the pointcut). For simplicity, I have included the pointcut definition in the ErrorHandler class, but a better practice would be to include it in another class so that it can be accessed throughout the application. For example:

    package iamjosh.samples;

    @Aspect
    public class SystemArchitecture
    {
        // matches on all methods called in the service package
        @Pointcut("execution(* iamjosh.samples.service.*.*(..))")
        public void serviceMethod() {}
    }

The ErrorHandler could then be revised to log service method call exceptions in a special way:

   @AfterThrowing(
        pointcut="iamjosh.samples.SystemArchitecture.serviceMethod()",
        throwing="exception"
    )
    public void processServiceMethodError(JoinPoint logged, RuntimeException exception)
    {
        // log the error message via the logging component
    }

The terminology can be quite confusing, but sometimes that’s just how it goes. Spring’s AOP documentation offers a nice high level overview of each topic. Defining pointcuts could be a topic on its own as well.

Let’s finish up our example. We now have to let Spring know about our ErrorHandler by configuring it as a Spring managed bean and enabling @AspectJ (in our Spring configuration file):


That should do it. Any exceptions thrown in the “iamjosh.samples” package and its descendants should now be logged (see caveats below). From a programmer’s perspective, we can now focus on business logic and trust that thrown exceptions are logged.

A couple of caveats (the first of which really got me):

  • Exceptions must cross the proxy boundary – Spring’s AOP framework utilizes a proxy around managed beans to implement aspect contracts. In order to be “caught” by the framework, an exception must cross the boundary by being thrown from a class to its caller.
  • The exception thrower must be Spring managed – in order to wrap the AOP proxy, Spring must manage the bean in order to weave an aspect into it. In other words, objects created with new will not have our error handling framework.
  • There are other ways to do this – Spring offers the flexibility to implement AOP in a number of ways, including the use of XML and annotations. Spring 2 offers a new style of XML configuration, but is still backwards compatible to the version 1 style. AspectJ can also be used on its own.

AOP is a much bigger topic than I can cover here, but I hope my relatively simply example will be of use in getting you going.