mayduTechblog

May 6, 2009

GWT-VL: Validation with Restlet GWT

Filed under: GWT, Java — admin @ 4:15 pm

A user of GWT-VL asked me if it is possible to use GWT-VL in conjunction with the Restlet-GWT project. The answer was ambivalent. Because you could already use GWT-VL as a client side only validation library with Restlet-GWT, but you could not profit from the connection between server side and client side, which is surely one of the strong points of the GWT-VL library. Before the 0.7 release line of GWT-VL the library was only able to connect server and client side with throwing ValidationException’s that would be sent back to the client with the use of RPC. The good thing with that is, that you stay on the Java road in that you will catch RuntimeExceptions of type ValidationException which should feel quite naturally to a Java programmer. Anyway, the problem with that approach is that it only works if you connect your client side via RPC to the server side. Clearly, Restlet-GWT doesn’t do that. So I decided to think about a way how I could integrate the server to client connection without the use of RPC. What I came up with is not exactly an Restlet-GWT integration but a general way of connecting the server and the client side of GWT-VL. The idea is to just pack the validation messages into Strings and pass them from the server side to the client side. With this approach I think virtually every framework will be able to make use of GWT-VL. So if you have choosen to communicate with your services via RPC, you just use the RuntimeException mechanism. If you do not use RPC than you are now able to let GWT-VL serialize its server side ValidationException’s into Strings that you can send back to your client. The client side has added functionality that allows it to process these Strings the same way it would process the ValidationException’s sent via RPC.

So enough with talking, lets dive into how you can gain the benefits of the use of a sophisticated validation library named GWT-VL while using RestletGWT on the backend.

The validation specifics on the client side have already been initially described on the first two posts about GWT-VL so if you haven’t read them by now I would advise you on reading them first here (Part 1) and here (Part 2).

Lets assume we have a page with two input fields which we try to validate on the client and on the server. The client side code could look something like this:

  1. final TextBox codewordBox = new TextBox();
  2. final TextBox tokenBox = new TextBox();
  3.  
  4.         validator.addValidators("codeword",
  5.                 new IntegerValidator(codewordBox)
  6.                         .addActionForFailure(new StyleAction("redBorder"))
  7.         );
  8.  
  9.         validator.addValidators("token",
  10.                 new IntegerValidator(tokenBox)
  11.                         .addActionForFailure(new StyleAction("redBorder"))
  12.         );

This is not different from the usual way of using the GWT-VL library. Differences arise when we start facilitating the server side. First we call the server side from the client side and handing over some input to the server side.

  1.        button.addClickListener(new ClickListener() {
  2.             public void onClick(Widget sender) {
  3.                 if(!validator.validate())
  4.                         return; //Some client side validation errors occured, validator actions are fired automatically
  5.                 // Add an AJAX call to the server
  6.                 final Client client = new Client(Protocol.HTTP);
  7.                 Form form = new Form();
  8.                 form.add("codeword", codewordBox.getText());
  9.                 form.add("token", tokenBox.getText());
  10.                 client.post("http://localhost:8888/validate", form.getWebRepresentation(), new Callback() {
  11.                     @Override
  12.                     public void onEvent(Request request, Response response) {
  13.                         String ret = ((StringRepresentation)response.getEntity()).getText();
  14.  
  15.                         if(!validator.processSerializedValidationErrorsSilently(ret)) {
  16.                                 //The server side signaled a validation error.
  17.                                 //All the actions will have been automatically invoked by
  18.                                 //the ValidationProcessor (as usual), so just return.
  19.  
  20.                                 return;
  21.                         }
  22.  
  23.                         //If we get here no validation errors were received from the server side
  24.                         //We would now direct the user to some other page, show him a success message, etc.
  25.                     }
  26.                 });
  27.             }
  28.         });

Here we see the standard GWT-VL stuff like: validator.validate() that just invokes all the client side validators and triggers the specific actions if an error occured. One thing that is new is the validator.processSerializedValidationErrorsSilently method. But before we come to that let me explain how the call to the server works. We use RestletGWT functionality for passing the value of the text boxes to the REST service. We use the POST method to post the data to the server side service. After the service returns its data, we feed whatever came from the service to the validator.processSerializedValidationErrorsSilently method. This method will automatically check whether the returned string denotes a serialized validation exception that the ValidationProcessor should consume or not. If it finds out that the returned String denotes a ValidationException in serialized form, it will be parsed and all the actions specified on the client side for the fields that the server side has deemed errorneous are invoked. If it sees that the returned String is not a serialized ValidationException, it just silently (thus the name) returns true and the code can assume that no error came from the server side (at least no GWT-VL validation error).

So let’s see what exactly happens on the server side. We have a Restlet resource that supports the POST method and validates the input:

  1. public class ValidateResource extends Resource {
  2.  
  3.     public ValidateResource(Context context, Request request, Response response) {
  4.         super(context, request, response);
  5.         getVariants().add(new Variant(MediaType.TEXT_PLAIN));
  6.         this.setModifiable(true); //Needed to support POST
  7.     }
  8.  
  9.     @Override
  10.     public void acceptRepresentation(Representation entity) throws ResourceException {
  11.         Form form = new Form(entity);
  12.         //Get the values from the post
  13.         String text1 = form.getFirstValue("codeword");
  14.         String text2 = form.getFirstValue("token");
  15.  
  16.         int codeword = -1;
  17.         int token = -1;
  18.  
  19.        //We convert the strings coming from the form to their intended type
  20.        //Note: If we would use RPC we wouldn’t need this step ;>
  21.  
  22.         try {
  23.                 codeword = Integer.parseInt(text1);
  24.         }catch(NumberFormatException ex) {
  25.                 try {
  26.                         ServerValidation.exception("noInteger", "codeword", text1);
  27.                 }catch(ValidationException ex2) {
  28.                         getResponse().setEntity(getValidationRepresentation(ex2));
  29.                         return;
  30.                 }
  31.         }
  32.  
  33.         try {
  34.                 token = Integer.parseInt(text2);
  35.         }catch(NumberFormatException ex) {
  36.                 try {
  37.                         ServerValidation.exception("noInteger", "token", text1);
  38.                 }catch(ValidationException ex2) {
  39.                         getResponse().setEntity(getValidationRepresentation(ex2));
  40.                         return;
  41.                 }
  42.         }
  43.  
  44.         try {
  45.                 new ServerValidation(false)
  46.                         .inRange(codeword,0, 100, "codeword")
  47.                         .inRange(token,0, 100, "token")
  48.                         .validate();
  49.         }catch(ValidationException ex) {
  50.                 //Ok, we got an validation error we talk that back to the client and quit the server side processing
  51.                 getResponse().setEntity(getValidationRepresentation(ex));
  52.                 return;
  53.         }
  54.         StringRepresentation str = new StringRepresentation("Success");
  55.         getResponse().setEntity(str);
  56.     }
  57.  
  58.     private StringRepresentation getValidationRepresentation(ValidationException ex) {
  59.         String serializedException = null;
  60.  
  61.         //Serialize the validation exception to a string which can be send over the wire to the client
  62.         serializedException = ServerValidation.serializeValidationException(ex);
  63.  
  64.         return new StringRepresentation(serializedException);
  65.     }
  66. }

Of course you probably have some code to make the parsing easier to write. You should create a method that will do this for you. But for clarity reasons I did go the “verbose” way. So you see what exactly needs to be done.

That’s basically all there is to do to get server and client side validation to act together as a  a pair like you are used to when using GWT-VL and all without RPC.

The first release to provide the forementioned features is the 0.7a release (but you really should download the newest 0.7b) wich you can get from Sourceforge.

Note: The new release also features support for parameterized custom validation messages.

So, thanks for listening and if you have comments, questions or feature requests do not hesitate to drop me a mail or use the Tracker and Forums on Sourceforge.

Kind regards,

Anatol Mayen

April 3, 2009

Input Validation with GWT - Part2 (ServerSide)

Filed under: GWT, Java — amayen @ 4:44 pm

Welcome to part 2 of the discussion of the GWT Validation Library.

In the first part I mostly spoke about why GWT-VL was made and how you can easily add richly presented client side validations to your GWT app.

In the second part I will speak about how you can connect the server side validations to the client side without much effort.

One of the design goals of the GWT Validation Library was to enable the developer to create richly presented client side validation while at the same time being able to profit from this “richness” even on the server side. So as the server side discovers errorneous input these errors should be presented to the user with the same mechanisms we already used to present the client side errors. To accomplish this goal something like a communication protocol was created. That protocol is able to push validation errors, sourced from the server side, to the client side and process them in much the same way the client side validations are processed. Through this functionality the developer is able to just concentrate on the plain validation on the server side with out having to code functionality that ensures that the errors from the server side are shown nicely to the end user.

So the GWT Validation Library consists of two parts:

  • The client side part that is responsible to do client side validations and show “nice” validation messages
  • The server side part that is responsible for checking the input and communicating validation messages back to the client

The server side communicates its validation messages through one object: ValidationException. This object holds the validation errors that occured on the server side. The client side has the functionality for taking that object, parsing it and invoking all the Actions’s that need to be invoked, thus resulting in the validation messages being presented to the user the same way the client side errors were presented to him/her.

So from the developers point of view its like he/she just defines how the errors should be presented once and on the server side he/she doesn’t have to care about anything view related.

Lets remember the dialog shown in part 1 of this series. Here it is again:

Input dialog

Input dialog

We have set it up with Validators for the fields and Actions that change the border color (background color in case of select boxes) to red if a validation error occured. Till now we only have client side validations so a malicious user could send ANY data to our backend services, additionally we might have checks that can only be done on the server side.

For this case there are utility methods provided by GWT-VL that you can use to simply check the input and return an object that the client validator understands.

Assume the following code from a service method that is responsible for saving the data the user put into the dialog above to the database:

public void addGame(Game game) throws ValidationException {
    new ServerValidation()
        .notEquals(game.getHomePlayer(), game.getAwayPlayer(), "homePlayer, awayPlayer");

    gameDao.save(game);
}

This code actually checks whether the player of the home team and the player of the away team aren’t equal. If they are not equal the call to gameDao.save(game); will happen. If they are equal the call to notEquals will throw a ValidationException. This is actually all you have to do to wire the client side “richness” of validation messages to the server side (at least on the server side, but not much more on the client side). The ServerValidation class is provided by the GWT-Validation Library and contains some basic checks. Of importance is the fact that the service method needs to declare to throw a ValidationException (could also declare to throw the more general RuntimeException).

On the client side all we have to do to let the client side code consume the validation messages and invoke the appropriate actions is the following:

    GameService ga = GameServiceAsync.instance();
    ga.save(game, new AsyncCallback() {
        public void onFailure(Throwable caught) {
            if(caught instanceof ValidationException) {
                ValidationException ex = (ValidationException) caught;
                validator.processServerErrors(ex); //The ValidationProcessor instance; check the first part of this series
            }
        }

        public void onSuccess(Void value) {
            //Saving successful! Close the dialog or something.
        }
    }

We have now connected server side validation messages with the client side presentation logic! As you see the GWT Validation Library makes it really easy to connect client and server side validations.

What if you need different methods for checking the input than the ServerValidation class provides? Easy. You just write your tests and if they fail, you can easily talk them back to the client by using another feature of the ServerValidation class:

public void saveGame(Game game) throws ValidationException {
    if(playerDisabled(game.getHomePlayer())) {
        //We discovered through some custom code that the home player choosen is actually disabled
        //at this time, so we don't allow to save this game.

        //Now we need to make sure that the error gets to the user "nicely"
        ServerValidation.exception("player_disabled", "homePlayer");
    }
}

So you can just invoke the ServerValidation.exception() method to communicate custom validation errors to the client. The client will, accordingly to the second parameter (”homePlayer”), invoke all the actions for the specific component. The error message will be created through the message key (”player_disabled”) given as the first parameter (just a key because it will be i18n on the client side to the locale the user is using. Check the next post for more info about i18n!).

Here you can see the possibilites the GWT-VL gives you as a developer. You can do all the checks you can think of on the server side. The GWT-VL library tries to not limit you with what you can do but enables you to still be able to profit from it (You will also see in the third part with how the library tries to NOT limit you on how exactly you want to implement i18n).

Bringing Hibernate to the game

As I mentioned in the first post I am using Hibernate in my projects. I wanted to have a way that the nicely presented validation messages could benefit from the Hibernate-Validator stuff. So I created some additional functionality to talk back Hibernate-Validator messages to the client. So I can use the Hibernate-Validator messages and present them to the user (of course fully i18n’able) with almost no effort.

We start with a simple introduction. We might have the following Hibernate-Validator annotated class:

class Car implements Serializable {

    private Long id;
    private int hp;
    private String model;

    @Id
    @GeneratedValue
    public Long getId() {
        return id;
    }

    @Range(min=10,max=500)
    public int getHp() {
        return hp;
    }

    @NotEmpty
    public String getModel() {
        return model;
    }

    ... //Setters ommited
}

So we have a Car that has members for its motor power and its model. Each of these members is annotated with Hibernate-Validator specific annotations, that constrain the possible values that these member variables can hold. These annotations will trigger validation of the fields values when a Car object is persisted or updated in the database layer through hibernate. For example we can not set the model to an empty string and successfully persist/update, because of the @NotEmpty annotation.

When we want to profit from these existing validations all we have to do is to edit our DAO code a little bit to hook the GWT Validation Library in the process. For example we could have a generic dao that does persisting and updating for all of the existing model classes. What we need to change are the methods responsible for writing data to the database. I usually create two methods: “persist” and “update” which look like this:

...
    public void persist(T instance) {
        getHibernateSession().persist(instance);
        getHibernateSession().flush();
    }

    public void update(T instance) {
        getHibernateSession().saveOrUpdate(instance);
        getHibernateSession().flush();
    }
...

To let the GWT Validation Library consume the validation errors thrown from Hibernate-Validator we would change these two methods to the following (we could also go for an aspect driven approach!):

...
    public void persist(T instance) {
        try {
            getHibernateSession().persist(instance);
            getHibernateSession().flush();
        }catch(InvalidStateException ex) {
            ExceptionConverter.createValidationException(ex);
        }catch(PropertyValueException ex) {
            ExceptionConverter.createValidationException(ex);
        }
    }

    public void update(T instance) {
        try {
            getHibernateSession().saveOrUpdate(instance);
            getHibernateSession().flush();
        }catch(InvalidStateException ex) {
            ExceptionConverter.createValidationException(ex);
        }catch(PropertyValueException ex) {
            ExceptionConverter.createValidationException(ex);
        }
    }
...

The ExceptionConverter is a class of the GWT Validation Library that processes the hibernate validation exceptions and creates ValidationException’s that are understood by GWT-VL. The Hibernate-Validator indicates on which member a validation failed through the name of the member. So be sure to name the properties on the client side, which you add validators to, the same as the corresponding property of the bean. So for example in the Car object we validate that the field hp is between 10 and 500. So on the client side the validations added to the input field for the ‘hp’ should be done like:

validator.addValidators("hp",
    new IntegerValidator(0,500)
        .addActionForFailure(new FocusAction)
);

Note that the first parameter to the addValidators method must be the same as the field name on the Car class.

The nice thing is, we now have client side and server side validation included while at the same time profiting from the rich representation of validation errors also on errors that come directly from hibernate. And, as its one of the main goals for the GWT-VL, we can i18n all the errors, that means even the Hibernate-Validator messages.

So that was it for today in the next part I will blog about the possibilities you have to i18n all of the validation messages that are built in and the custom ones that you probably will add.

Also the Showcase site was updated, there is a description functionality that informs the user about how correct input should look like for a specific field.

You can download the GWT Validation Library at https://sourceforge.net/projects/gwt-vl/

and see the official documentation on http://gwt-vl.sourceforge.net/

March 20, 2009

Input Validation with GWT

Filed under: GWT, Java — amayen @ 12:10 am

The Google Web Toolkit is a great way to build webbased frontends for applications. There comes quite some functionality out of the box, such as a Swing-like development style and the fundamental functionality used to build Rich-Client Webbased-Frontends. It is very good in creating a fluid interaction feeling, without the end-user being constantly interrupted in his workflow by page loading and the like. Additionally there are many libraries out there to even enhance the possibilities of GWT, like SmartGWT, Gilead, etc.

Where it lacks, is the possibility to validate the data that a user inputs. Which I find quite surprising for a web development toolkit. So in order to fill the gap, there are already some projects existing including:

Unfortunately there are some issues with these frameworks that made them appeal to not be the right thing for what I had in mind.

The GWT-Validator’s biggest disadvantage is, that its functionality is tied to the client side, so the most important part in a security point of view is not addressed. Another big problem is that it is not supported nor further developed by the original authors.

The GWT Validation Framework does bring validation to the client and server side. One strong point about it, is that the validation code only needs to be written once and can then be automatically used on the server and the client side. Unfortunately it also has some issues of which the main drawbacks for me are:

  1. No help for setting up “nice” client notifications of validation errors
  2. No localization of validation messages yet
  3. Conflicts in a way with Hibernate-Validator

As I’m quite convinced of the usage of Hibernate in my projects and already use the Hibernate-Validator capabillities I do not want to drop them in favor of the GWT Validation Framework’s style of doing these kind of things.

Because of the forementioned shortcomings of the existing frameworks and my believes in Hibernate I began work on my own framework which I call the GWT Validation Library (see here for a little Showcase).

The main aspects I wanted to achieve were:

  • Make it easy for the developer to set up “nice” client side notifications
  • Validation errors on the server side should also be shown “nicely” on the client with little overhead
  • Integration with the Hibernate-Validator framework
  • I18n of the validation messages
  • Support of writing custom validators
  • Action concept for showing the validation errors
  • Support of writing custom actions

I think I have achieved these goals now and am quite happy with the result. So here goes the introduction of what you can do with the GWT Validation Library.

Easily add validation on the client side:

  1. ValidationMessages messages = new ValidationMessages(); //Contains the validation messages. Fully localizable!
  2.  
  3. ValidationProcessor validator = new ValidationProcessor(messages);
  4.  
  5. //We might have some TextBox that should only contain numeric values from 0 to 15
  6.  
  7. validator.addValidators("number",
  8.     new IntegerValidator(numberTextBox, 0, 15)
  9.         .addActionForFailure(new FocusAction()) //Adding an action in case of a validation failure
  10. );

The result is that we have now added client side validation to a TextBox element that only accepts numbers from 0 to 15 inclusively, if the widget fails validation the focus will be put on it, because we added an FocusAction to it! We could now go on and add additional validator constraints for different widgets or even more than one validator or action for one widget.

For example we could also do this:

  1. validator.addValidators("number",
  2.     new IntegerValidator(numberTextBox, 0, 15)
  3.         .addActionForFailure(new FocusAction()) //Adding a focus action
  4.         .addActionForFailure(new StyleAction("validationFailedBorder")) //… and a style action
  5. );

Now we added two actions! The FocusAction that focuses the widget and a style action, that adds a specific style to the widget when validation fails (for example the widgets border could be set to red color).

We can setup validation like this for all the components we would like to validate. All we have to do when the user is finished entering data and wants to invoke an action is:

  1. if(!validator.validate())
  2.     return; //Validation failed. Don’t do anything
  3. else {
  4.     //Validation was correct. Invoke the action you need to invoke
  5. }

In the case of a failing validation all the actions are invoked (or only the ones for the first error, depending on configuration). So the user is presented with “fancy” validation error messages that guide him through correct data entry.

An example would be:

Dialog in its initial state

Dialog in its initial state

And after triggering the validation process:

Dialog with failed validations shown

Dialog with failed validations shown

In order to make the development of a consistent validation user experience even easier it is possible to create your own custom validators and your own custom actions, so you can for example create custom validators that are prebuilt with the needed Actions so you do not have to repeat yourself in adding the same Actions over and over again.

So, I think thats it for the moment. But there is quite some stuff more that the GWT Validation Library is capable of (Serverside validation, I18n, etc.) so stay tuned for the next post or just check for yourself.

In the next part of this series I will examine the possibilities on how to connect server side validation with the client side and additionally adding Hibernate-Validator to the game.

You can download the GWT Validation Library here.

You can visit the showcase site here.

Powered by WordPress