This article is based on Spring Roo in Action, to be published Summer-2011. It is being reproduced here by permission from Manning Publications. Manning publishes MEAP (Manning Early Access Program,) eBooks and pBooks. MEAPs are sold exclusively through Manning.com. All pBook purchases include free PDF, mobi and epub. When mobile formats become available all customers will be contacted and upgraded. Visit Manning.com for more information. [ Use promotional code 'java40beat' and get 40% discount on eBooks and pBooks ]
The Bean Validation API
Introduction
Validation is a difficult topic for any application architecture. You may ask yourself a bevy of questions, such as:
- Where do I perform validation, at the web layer, in the middle tier, or in my database?
- How do I validate? Should I use a validation rules engine, scripted code, data-driven rules, or annotations?
- How will my errors be returned? Should I localize the messages?
There are many APIs available to implement validation rules. Spring MVC has its own validation API, but it is MVC based and doesn’t necessarily suit the embedding rules within the entities. We want to do this because it helps us to encapsulate the behavior of validation within the entity tier. A more object-driven approach is needed. Enter the Bean Validation API.
The Bean Validation API is a recent standard. It was created by the Java EE Expert Group to address the lack of a standard validation API on the Java EE platform. This API uses Java annotations to define specific rules, which are attached to the attributes of a Java Bean. Some validations are built into the framework, such as @NotNull, @Null, @Min, @Max, @Past, @Future, @Pattern, and @Size. You can also define your own classes for validation purposes and register them using @AssertTrue or @AssertFalse.
Let’s get started with the Bean Validation API by building a simple example. We’ll define a Java Bean annotated with validations, and then we will use JUnit unit tests to exercise the Bean Validation API and generate validation errors. Later, we’ll show you how to use Bean Validation from Roo, and how to customize validation messages and build your own constraints. But, first, let’s set up our project.
Generating our project
Let’s jump on and take the Roo Shell for a test drive by generating our project. The first step is to create a directory for our project:
1 | $ mkdir tracker |
Go into the directory—this is where Roo will generate the project directories and artifacts:
1 | $ cd tracker |
Start Roo:
1 | $ roo |
Notice Roo’s shell prompt is simply:
1 | roo> |
This prompt will change based on the last command issued. Let’s keep an eye on the Roo prompt as we move forward. Now let’s start creating our project by typing pr and pressing the [TAB] key twice:
1 | roo> proj [TAB] [TAB] |
When we use the [TAB] key, Roo will automatically select the matching command with the first required option project –topLevelPackage, requiring us to only then type the project’s top level package. When we press the tab key, Roo will display the list of commands based on the starting characters typed. If there is more than one command, we will be given a list of matching commands. In this case, we get project because it is the only command starting with pr. Roo then prompts us with any required elements. For our project, the only required element is the top level package. Let’s choose a package name of org.distracted.tracker.
1 | <code> roo> project --topLevelPackage org.distracted.tracker </code> |
The last element in the package defines the name of the application by default—tracker. This is due to the package and not the physical directory name. It also configures:
- The application’s location using the default URL of http://localhost:8080/tracker
- The project name display in SpringSource Tool Suite as tracker.
- Maven Group Id: org.distracted.tracker.
- Maven Artifact Id: tracker.
- Maven Project Name: tracker.
1 2 3 4 5 6 7 8 9 10 | Created /code/roo/tracker/pom.xml Created SRC_MAIN_JAVA Created SRC_MAIN_RESOURCES Created SRC_TEST_JAVA Created SRC_TEST_RESOURCES Created SRC_MAIN_WEBAPP Created SRC_MAIN_RESOURCES/META-INF/spring Created SRC_MAIN_RESOURCES/META-INF/spring/applicationContext.xml Created SRC_MAIN_RESOURCES/log4j.properties org.distracted.tracker roo> |
Notice the capitalized path elements that Roo has created? These are constants that are used throughout Roo commands. Now, let’s set up our database.
Setting up the database
To make this project easy to deal with, we will assume you don’t have a database installed on your machine. No big deal, there are a number of embeddable and standalone databases you can use. In our case, let’s use the Hypersonic SQL standalone database. Here is the persistence configuration setup command to run from the Roo shell.
1 | roo> persistence setup --database HYPERSONIC_PERSISTENT --provider HIBERNATE |
SAVE SOME TYPING
Remember, in the Shell, you can type the first two or three characters of this command—for example, per [TAB]—and Roo will complete the command for you. This goes for your options and values as well. You can type — [TAB] to see what options are available, and when an option is selected such as database, you can hit [TAB] to get the available options.
Now that we’ve created the project and installed Hibernate and JSR-303 Validations, we can move onto our discussion of the Bean Validation API.
Defining a validated bean
Using the Roo shell, we will create a ValidationExercisor class, which will allow us to experiment with the Bean Validation API:
1 | roo> class --class ~.validations.ValidationExercisor |
This command just creates a class in the org.distracted.tracker.validations package in src/main/java. In listing 1 below, we edit this class and define a simple JavaBean with some attributes that hold validation annotations. We define the class with the @RooJavaBean annotation so that the Roo shell will automatically generate getters and setters for us. We also define three fields—a String, a Date, and a BigDecimal, and we define several validation annotations for each one.
Listing 1 ValidationExercisor.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | package org.distracted.tracker.validations;
import java.math.BigDecimal;
import java.util.Date;
import javax.validation.constraints.DecimalMax;
import javax.validation.constraints.DecimalMin;
import javax.validation.constraints.Future;
import javax.validation.constraints.NotNull;
import org.hibernate.validator.constraints.Length;
import org.springframework.roo.addon.javabean.RooJavaBean;
@RooJavaBean #1
public class ValidationExercisor {
@NotNull #2
@Length(min = 1, max = 10)
private String myString;
@DecimalMin("0.0") #3
@DecimalMax("9999999.9")
private BigDecimal myNumber;
@Future #4
private Date dueDate;
}
(#1) Generates getter and setter methods for this class in a file named ValidationExcercisor_Roo_JavaBean.aj
(#2) The myString attribute cannot be null and must be between 1 and 10 characters in length.
(#3) The myNumber attribute may be null but, if specified, will range between 0 and 9999999.9.
(#4) This date, if specified, must be in the future from the time when the validation is performed. |
Although this isn’t an entity, we wanted to start out our discussion of Bean Validation by showing you that you can use it pretty much wherever you like it.
Roo entities
Roo Entities are JPA-annotated classes that map data to a database and specify data-type constraints and validation rules using annotations such as @NotNull, @Past, and @Size.
Spring supports Bean Validation annotations in a number of places, such as in web form validation, entity validation, and in plain JavaBeans.
Roo annotations—not just for generated code
If you create classes below your top-level package, the Roo shell will automatically look at them each time they are saved and generate any AspectJ ITDs required to add the features that you want. That’s why we can use the annotation @RooJavaBean above and can easily add features such as @RooToString to automatically generate a toString() method. Look for add-ons to be developed that take advantage of this feature, adding support for a wide variety of features without requiring you to write code.
Later on, we’ll see how we can customize validations by adding our own messages and validators but, for now, let’s get started and test our validations.






April 20, 2011
Spring Framework