Javax Annotation and Hibernate Validator - A Pragmatic Approach

Introduction

 
As you know, modern programming paradigms suggest validating a Java Bean with annotations. A Java Bean can be validated in many ways. But we must opt for the simplest and most robust one. With the introduction of the Java Annotation feature, programming has become easier and lets developers write less code. In this article, I will show you the significance of the Hibernate validator and Javax annotation in a Java Bean. The API provided by the Hibernate validator and Javax annotation has made the developer's life much easier to provide validation instantly.
 
Technicalities
 
The Java EE 6 platform provides a set of annotations for bean validation. This bean validation API can be applied to the field and method level to do validation. Apart from that, the Hibernate validator provides some extra validation annotation to ease the development and also it provides the shortcut way to define your own custom validation constraints. The Javax bean validation API provides the following most frequently used annotations.
  • javax.validation.constraints.Digits
  • javax.validation.constraints.Min
  • javax.validation.constraints.Max
  • javax.validation.constraints.NotNull
  • javax.validation.constraints.DecimalMax
  • javax.validation.constraints.DecimalMin
  • javax.validation.constraints.Pattern
  • javax.validation.constraints.Null
  • javax.validation.constraints.Size
The Hibernate validator provides the following commonly used annotations for validation.
  • org.hibernate.validator.constraints.URL
  • org.hibernate.validator.constraints.NotEmpty
  • org.hibernate.validator.constraints.NotBlank
  • org.hibernate.validator.constraints.Length
  • org.hibernate.validator.constraints.Email
  • org.hibernate.validator.constraints.CreditCardNumber
In case of product or project development we must use both the annotations for bean validation. It is always recommended to use the relevant annotations in the field level of the Java Bean since it increases the readability and minimizes the burden of bug fixing and maintenance problems.
 

How to validate a Java Bean

 
To do bean validation, you need to use the Javax bean validation API, Hibernate validator API and logging API. For the usage of this validation, you need to use the following jar files:
  • hibernate-validator-4.3.1.Final.jar
  • jboss-logging-3.1.0.CR2.jar
  • validation-api-1.0.0.GA.jar
All the preceding jar files can be downloaded from the site "mvnrepository.com". If you are using a Maven project then you need to use the following dependencies as mentioned below.
  1. <dependencies>  
  2.        <dependency>  
  3.              <groupId>junit</groupId>  
  4.              <artifactId>junit</artifactId>  
  5.              <version>4.11</version>  
  6.              <scope>test</scope>  
  7.        </dependency>  
  8.        <dependency>  
  9.              <groupId>org.hibernate</groupId>  
  10.              <artifactId>hibernate-validator</artifactId>  
  11.              <version>4.3.1.Final</version>  
  12.        </dependency>  
  13. </dependencies>  
The dependency for junit is optional since it depends upon your project requirements.
 
Let us see a brief structure of a bean provided with various annotations.
  1. public class Bean1 {  
  2.     // ~~~~~~~~~~ javax annotations for validation ~~~~~~~~~~  
  3.     @Digits(integer = 2, fraction = 0, message = "The value of age can not be more than 2 digits")  
  4.     @Min(value = 18, message = "The minimum age should be 18")  
  5.     @Max(value = 50, message = "The maximum age can not more than be 50")  
  6.     private int age;  
  7.     @NotNull(message = "First Name can not be null ... ")  
  8.     private String firstName;  
  9.     @DecimalMax(value = "99999.999", message = "The decimal value can not be more than 99999.999 ")  
  10.     @DecimalMin(value = "1.00", message = "The decimal value can not be less than 1.00 digit ")  
  11.     private float amount = 0f;  
  12.     @NotNull  
  13.     @Pattern(regexp = "^\\d{6}", message = "Invalid zip code, Indian zip code should be 6 digit")  
  14.     private String zipCode;  
  15.     // ~~~~~~~~~~ Hibernate provided annotations for validation ~~~~~~~~~~  
  16.     @CreditCardNumber(message = "Invalid credit card number")  
  17.     private String creditCard;  
  18.     @Email(message = "Invalid email id")  
  19.     private String emailId;  
  20.     @Length(max = 50, min = 10, message = "The message description should be within 10 to 50 characters")  
  21.     private String description;  
  22.     @NotBlank(message = "SurName can not be blank")  
  23.     // It is only applicable to String  
  24.     private String surName;  
  25.     @NotEmpty(message = "The list can not be empty")  
  26.     private List<String> countryList;  
  27.     @URL(message = "Invalid website address")  
  28.     private String website;  
  29.     // ~~~~~~~~~~ Custom annotations for validation ~~~~~~~~~~  
  30.     @Password  
  31.     private String password;  
  32.     @IBAN  
  33.     private String ibanActNo;  
  34.     // ~~ getter and setter methods below  
  35. }  
The preceding Java class contains many fields that require validation. If the preceding bean is populated with data then we need to validate the bean with the default validator provided by the Hibernate API. The brief code structure is given below.
  1. ValidatorFactory factory = Validation.buildDefaultValidatorFactory();  
  2. Validator validator = factory.getValidator();  
  3. Set<ConstraintViolation<Bean1>> set = validator.validate(bean);  
  4. noOfViolations = set.size();  
  5. if (noOfViolations != 0)  
  6.        throw new BeanValidationFailedException(set);  
The code above is very precise and provides a set of violations. This is all about the default annotations provided. What about your own custom annotations that may be required as per your project requirements? The Javax bean validation API provides the easiest way to define and integrate your own annotations for validation. Let us use an example of password. The rule for the password is that it should be within 6 to 20 characters, one special character, one upper case and one numeric character. For this purpose we have defined an annotation called "Password" and we must define one Java class called "PasswordValidator" by implementing "javax.validation.ConstraintValidator". That's it. You are done now. You can now freely use your annotation in any Java Bean. Let us see the brief code structure for the preceding.
  1. @Target({ METHOD, FIELD, ANNOTATION_TYPE })  
  2. @Retention(RUNTIME)  
  3. @Constraint(validatedBy = PasswordValidator.class)  
  4. public @interface Password {  
  5.     /** 
  6.      * This method is used to provide a default message 
  7.      * @return 
  8.      */  
  9.     String message() default "{Invalid password, valid password : one Upper case, one special char, one number, total length 6 t0 20 chars}";  
  10.     Class<?>[] groups() default {};  
  11.     Class<? extends Payload>[] payload() default {};  
  12. }  
The complete project for the validation can be downloaded from the following link.
 
You can download the complete project, extract it and import the project as a Maven project. If you have the internet then you can run the project with the command "clean compile install". If you want to manually run the project then run the Java class "App.java". If you do not want a Maven project then download all the preceding jar files and place the jar files inside a folder called "lib" in your Eclipse project and set the Eclipse build path. In this project I have defined two custom annotations, you can also define you own annotations and test the application. 
 
Conclusion
 
This article is meant for the novice user. It will provide you a cleaner approach of using Javax annotation and the Hibernate validator for bean validation. I hope you will enjoy my article.
 
References