Spring like Validation in DWR

Posted by Tejus Parikh on October 19, 2007

One challenge of a hybrid AJAX and Spring MVC approach is consistent error handling. Since DWR does not have standard validation support, ad-hoc solutions tend to proliferate throughout the source code, leaving both the developer and the end-user confused. This is in contrast to Spring, which includes a validation as part of it’s form processing workflow. Our solution was to graft Spring-like validation on top of our DWR controllers. We’ve implemented this approach on DWR 2.0. Our methods, exposed via DWR now look like this:


    @RemoteMethod

    @AjaxValidators(PersonalInfoValidator.class)

    public void updatePersonalInfo(PersonalInfo pi) {

Now lets look at the magic that makes this possible. The first step is to add a filter in the allow section of the dwr.xml configuration file.

    
This line allows you to intercept a call on a dwr method and process any annotations that you might have added on the method (such as @AjaxValidators). The next step is to implement an AjaxFilter. This class has to process the annotations, find the appropriate bean, then preform the validation.

public class AjaxValidationFilter implements AjaxFilter {



    private ApplicationContext applicationContext;



    public AjaxValidationFilter() {

        applicationContext = (WebApplicationContext) ThreadContext.get(ThreadLocalSpringCreator.BEAN_FACTORY_KEY);

    }



    public Object doFilter(Object obj, Method method, Object[] params, AjaxFilterChain chain) throws Exception {

        AjaxValidators ann = method.getAnnotation(AjaxValidators.class);

        boolean throwErrors = false;

        if(ann != null) {



            int lastParamToValidate = Math.min(params.length, ann.value().length);

            BindException[] errors = new BindException[lastParamToValidate];



            for(int i = 0; i  validatorClass ) throws Exception {

        if(validatorClass == null) return null;

        String[] possibleValidators = applicationContext.getBeanNamesForType(validatorClass);

        return (Validator) applicationContext.getBean(possibleValidators[0]);

    }

}

There’s a few things of note. First is that the value of the annotation is an array. Therefore, you can have one validator per argument to your DWR method. Secondly, we need access to the context where the DWR beans are defined, so that we can find the correct instance of the validator. We use an instantiated bean so that we can inject Managers and other properties into the validator to validate business layer requirements (such as searching the database for name conflicts). The AjaxValidationException class is a normal runtime-exception class that contains an array of org.springframework.validation.Errors objects for errors. It then internally translates this information into a list of NameValue pairs for easy access in javascript. This is our approach, but there are other ways to do this. Now all errors will be marshaled into a class that has the property javaClassName set to net.vijedi.ajax.validation.AjaxValidationException. This allows you to do whatever you need in your error handler. The simplest thing to do is update the contents of a placeholder div by looping through the errors array. However, if your exception can give you name-value pairs, then it’s entirely possible to highlight specific form fields.

Tejus Parikh

I'm a software engineer that writes occasionally about building software, software culture, and tech adjacent hobbies. If you want to get in touch, send me an email at [my_first_name]@tejusparikh.com.