-
Notifications
You must be signed in to change notification settings - Fork 45
devon4j validations
For validations devon4j includes the Hibernate Validator as one of the available libraries in the pom.xml file
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
Hibernate Validator allow us to check the values by adding annotations in our Java classes.
In My Thai Star app we can find validations for some fields that we receive from the client.
The main part of the inputs from the client is related to the booking process. The client needs to provide: name
, comment
, bookingDate
, email
and assistants
.
@NotNull
private String name;
...
private String comment;
@NotNull
@Future
private Timestamp bookingDate;
...
@NotNull
@EmailExtended
private String email;
...
@Min(value = 1, message = "Assistants must be greater than 0")
@Digits(integer = 2, fraction = 0)
private Integer assistants;
-
@NotNull
checks that the field is not null before saving in the database. -
@Future
, for dates, checks that the provided date is not in the past. -
@Min
declares a minimum value for an integer. -
@Digits
checks the format of an integer. -
@Email
is the standard validator for email accounts. In this case the standard validator is not checking the domain of the email, so for My Thai Star we added a custom validator called '@EmailExtended' that is defined in a new 'general/common/api/validation/EmailExtended.java` class. In the next section we will see it in more detail.
In Jump the Queue app we have some inputs from the client so let’s add some validations for that data to avoid errors and ensure the consistency of the information before trying to save to data base.
When registering a visitor the client provides:
-
username: must be not null and must match the format
<name>@<domain.toplevel>
. -
name: must be not null.
-
phoneNumber: must be not null and must match a sequence of numbers and spaces.
-
password: must be not null.
-
acceptedCommercial: must be not null.
-
accepterTerms: must be not null.
-
userType: must be not null.
As we have just mentioned the name of the visitor must be not null, to do so Hibernate Validator provides us with the already mentioned @NotNull
annotation (javax.validation.constraints.NotNull).
We are going to add the annotation in the 'visitormanagement/dataaccess/api/VisitorEntity.java' just before the field name
@NotNull
private String name;
Run the app with Eclipse and, using Postman or a similar tool, call the register resource (POST) http://localhost:8081/jumpthequeue/services/rest/visitormanagement/v1/visitor
providing in the body a visitor object without a name
{
"username": "[email protected]",
"phoneNumber": "1234567",
"password": "12345",
"acceptedCommercial": "true",
"acceptedTerms": "true",
"userType": "false"
}
You will get a ValidationError message regarding the name field
In the case of the email, as we have already commented for My Thai Star, using the @Email
annotation for validations will allow to enter emails like something@something
. This does not fit the app requirements, so we need to add a custom email validator.
Add an annotation EmailExtended.java
in a new general.common.api.validation
package.
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.validation.Constraint;
import javax.validation.Payload;
import javax.validation.constraints.Email;
import javax.validation.constraints.Pattern;
@Email
@Pattern(regexp = ".+@.+\\..+", message = "Email must specify a domain")
@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {})
@Documented
public @interface EmailExtended {
String message() default "Please provide a valid email address";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
This validator extends the @Email
validation with an extra @Pattern
that defines a regular expression that the fields annotated with @EmailExtended
must match.
Now we can annotate the username field in with @NotNull
and @EmailExtended
to fit the app requirements.
@NotNull
@EmailExtended
private String username;
Then, if we try to register a user with a null email we get the ValidationError with message "{email=[may not be null]}"
And if we provide an email that does not match the expected format we get the related ValidationError
Finally if we provide a valid email the registration process ends successfully.
For validating the phone, apart from the @NotNull
annotation, we need to use again a custom validation based on the @Pattern
annotation and a regular expression.
We are going to follow the same approach used for EmailExtended validation.
Add an annotation Phone.java
to the general.common.api.validation
package. With the @Pattern
annotation we can define a regular expression to filter phones ("consists of sequence of numbers or spaces").
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.validation.Constraint;
import javax.validation.Payload;
import javax.validation.constraints.Pattern;
@Pattern(regexp = "[ 0-9]{0,14}$", message = "Phone must be valid")
@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {})
@Documented
public @interface Phone {
String message() default "Phone must be well formed";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
Then we only need to apply the new validation to our phone field in 'visitormanagement/dataaccess/api/VisitorEntity.java'
@NotNull
@Phone
private String phoneNumber;
As last step we can test our new validation. Call again the service defining a wrong phone, the response should be a ValidationError like the following
However, if we provide a valid phone the process should end successfully
In this chapter we have seen how easy is to add validations in the server side of our devon4j applications. In the next chapter we will show how to test our components using Spring Test and devon4j's test module.
Next chapter: Testing in devon4j
This documentation is licensed under the Creative Commons License (Attribution-NoDerivatives 4.0 International).