Annotated Object Validator

The Annotated Object Validator is a flexible framework for defining validators for objects and their fields within an application.

Validation conditions are specified on objects and fields using Java Annotations, negating the need to create separate objects for validation, or clutter business logic with extra validation code.

Previously, you may have written validation code resembling the following (example using Spring validation):

public class FormObject {
    String username;
    String password;
    String date;
    
    public String getUsername() {
        return username;
    } 
    
    public String getPassword() {
        return password;
    }
    
    public String getDate() {
        return date;
    }
    
    public FormObject(String username, String password, String date) {
        this.username = username;
        this.password = password;
        this.date = date;
    }
}
public class FormValidator implements Validator {

    public boolean supports(Object object) {
        return object instanceof FormObject;
    }

    public void validate(Object object, Errors errors) {
        ValidationUtils.rejectIfEmpty(
            errors, object.getUsername(), "username.required");
        ValidationUtils.rejectIfEmpty(
            errors, object.getPassword(), "password.required");
        ValidationUtils.rejectIfEmpty(
            errors, object.getDate(), "date.required");
        try {
            new SimpleDateFormat("dd/MM/yyyy").parse(object.getDate());
        } catch (ParseException e) {
            errors/rejectValue("date", "date.invalidDate");
        }
    }
}
    @Controller
    public class FormController {
        
        private Validator validator;
        
        public void setValidator(Validator validator) {
            this.validator = validator;
        }
        
        @ModelAttribute("formObject")
        public FormObject getNewFormObject() {
            return new FormObject("user", "pass", "11/11/2008");
        }
        
        public String doForm(
            @ModelAttribute("formObject") FormObject formObject,
            BindingResult result) {
         
            this.validator.validate(formObject, result);
            if (!result.hasErrors()) {
                // Do stuff...
            }   
        }
    }

In the above example, validation code is abstracted to a different class. If an unexpected error is encountered when processing FormObject , then FormValidator must be searched in order to find the particular validation condition that failed. Consider the following example as an alternative:

public class FormObject {

    @ValidateRequired
    String username;
    
    @ValidateRequired
    String password;
    
    @ValidateRequired
    @ValidateDate
    String date;
    
    public String getUsername() {
        return username;
    } 
    
    public String getPassword() {
        return password;
    }
    
    public String getDate() {
        return date;
    }
    
    public FormObject(String username, String password, String date) {
        this.username = username;
        this.password = password;
        this.date = date;
    }
}
    @Controller
    public class FormController {
        
        @ModelAttribute("formObject")
        public FormObject getNewFormObject() {
            return new FormObject("user", "pass", "11/11/2008");
        }
        
        public String doForm(
            @ModelAttribute("formObject") FormObject formObject,
            BindingResult result) {
         
            AnnotatedObjectValidator.validate(
                formObject, new SpringValidationResult(result));
                
            if (!result.hasErrors()) {
                // Do stuff...
            }   
        }
    }

The first thing we notice in this second example is that FormObject has grown slightly- each field now has an annotation on it describing how that field should be validated- there's no longer any need to search through a separate class. In fact, the second thing we notice is that there is no longer a separate validator class to search through!

The Annotated Object Validator framework provides a means to save writing extra code and make validation conditions more readily apparent when browsing code, leading to imporoved maintainability. The framework provides a variety of built in validators, as well as a flexible toolkit for writing custom validation code.