Posts tagged ‘jboss7’

Introduction

In this entry I’ll describe how to perform data validation for GWT 2.3+ application running on JBoss AS 7.1. On both client and server I’ll use jsr-303 annotations (a.k.a. beanvalidation). The source code for this project is meant to be a startup project for real world application and thus contains 6 modules and dependency to proprocessor project (available also on github).

Requirements

Base requirement is that application can handle incomming data or fail gracefuly. It means that user should be notified about invalid data she entered in such a way she can correct it and save. On the other hand we still want to guarantee that server is protected against anyone bypassing this meaningful road adding wrong data. This leaves us with two paths:

  • client-side validation which can inform user of what she’s doing wrong and how to correct it
  • a double check layer on server side that will do exactly the same and thus maintain data-integrity

A careful reader has already noticed that there’s going to be some redundancy which in worst case might cause a maintenance-nightmare in which client and server  are completely separated parts of application and use duplicated parts of code for doing the same thing while doing other things different. To avoid it we’re going to introduce jsr-303 validations for defining our validation rules and annotation preprocessor, taking care of tranforming annotations into validation rules understood by client-side layer of application.

There might be questions raised why not to use gwt-beanvalidation – this feature has been brought to official GWT branch in 2.5 release. As side project it was possible to use it with GWT 2.4, which leaves 2.3 users on their own 🙂

Application flow/Tools

First let’s start with application data-flow, so we can follow it and mark critical parts in terms of data-validation.

Our GwtValidation application is a GWT-RPC application. On server side data is going to come from RDBM, throught JPA2.0 layer (this will be handled by Hibernate) but entities will not be used on client-side. Instead there will be simple pojo, with fields rewritten from entity (handled by dozer). DAO and Service layers will be defined as EJB3 stateless beans. Further down the line, DTO’s will be handled by GWT-RPC service (defined as 3.0 servlets) and serialized/deserialized into client-side code.

On the client-side data is available as DTO and transformed into form acceptable by user (html).

Since part of our application lives totally on client-side and is clueless of what serves its data (or at least this is assumed), we cannot rely on client-side only. That’s why there are 2 steps of the flow that require validation.

On the other hand we could resign of client-side totally, but this would require connection between errors generated on server-side with client which might get ugly – it’s easier do real client-side and user server side as last-resort, so it’s errors might be little less explanatory.

Introducing jsr303…

Both client and server operate on the same beans – DTO’s. On server-side DTO’s are converted into entities and back, while client-side operates on DTO’s only. That’s why they seem to be the best candidates for placing jsr-303 annotations.

The idea is that unless validation for DTO’s is succesfull they will not get converted into Entities, so validation should be performed on service-level methods.

…on server-side

Our services are EJB3 stateles beans injected into servlets using EJB DI. To get the job done we could call manually validation in each method, check results and in case of errors send them back to client. But this looks a looot of duplicated code, so another concept was introduced – BeanValidationInterceptor, which is EJB3 interceptor and can handle validation through available Validator object (injected by container) and in case there are any errors stop execution.

This leaves us with small problem – how to inform Interceptor that we want certain object to get validated. We could mark class as validable, but this is not really flexible solution as someone might want to operate on instances instead of classes. So maybe annotate service method parameters with just 2 annotations:

Sure we don’t want to perform any validation if field is null – so why not include it in Valid handling, well there are cases where you want NotNull and not necesarily Valid so this distinction is just for consistency.

This gives us enough flexibility and removes redundant code on server side. And we do get some bonus – orignally it was designed only for DTO’s but in case of search it’s good to have SearchDTO which might be validated using the same mechanism, eg. we don’t want to peform search when we got null search object.

… on client-side

Here it is somewhat more complicated. First we need to define our validation DSL – this is responsibility of Constraints class which contains all methods that should reflect available jsr-303 annotations and form our vocabulary. All of them return Constraint object with methods used when doing real validation.

Second part is to convert annotations into executable code – this responsibility of Jsr303Processor, which analyzes classes during compilation and generates class suffixed Constraints whose methods resemble its name after validated fields. So when a field firstName should be validated, there is a corresponding static method firstName() which returns List<Constraint> – these are validation rules.

Third step is applying them. Original idea was to apply these inside java code but than field value and field validation would be defined in different places which might be somewhat confusing. That’s why an abstrac type ValidableRow which is extended by TextRow – which is a proxy to the real form field and additionally is capable of gathering validation rules and passing them further.

The rest is contained in ValidableForm which contains some bilerplate to handle save action, apply validation and either save data or display validation errors.

Summary

Annotation preprocessor is really powerful tool and the author of this post is fully aware that project describe might seem a little childish. It’s purpose is to balance preprocessor and GWT-RPC project that depends on it. There are many topics completely omitted – eg. multiselect boxes, different return types, making pre-processor type-aware and improving code generation (notBlank instead of notNull for String fields/TextBox are a good example) and not to mention custom validators which are fully supported by jsr-303 spec.

In case you’re interested in any of those please leave some comments and I’ll try to come up with another post describing it in more detail.