Building custom validation constraints

In the previous section, we had a quick look at the built-in validation constraints offered by the Bean Validation framework. There may be cases where you may want to build your own validation constraints. The Bean Validation framework supports that as well.

The core contracts that you should implement for a custom validation constraint are as follows:

  • Annotation for the custom validation constraint
  • Implementation of the javax.validation.ConstraintValidatorContext interface. This class contains your custom validation logic
  • Definition of a default error message

Let's build a custom validation constraint for checking whether a department with the same name already exists for a given location. This constraint avoids the duplicate department entities.

The first step is to build an annotation for the custom constraint that you are going to construct. The Bean Validation framework specification demands the following attribute definitions in a constraint annotation:

  • message: This attribute returns the default key for reading the validation error messages.
  • groups: This attribute specifies the validation groups to which this constraint belongs to. This is default to an empty array of the Class<?> type.
  • payload: This attribute can be used by clients for assigning custom payload objects to a constraint. This attribute is not used here.

Let's define an annotation for the custom validation constraint, ValidDepartmentValidator, which we are going to build next:

//Other import statements are omitted for brevity 
import java.lang.annotation.ElementType; 
import java.lang.annotation.Retention; 
import java.lang.annotation.Target; 
import java.lang.annotation.RetentionPolicy; 
import javax.validation.Constraint; 
import javax.validation.Payload;  
 
//@Constraint links a constraint annotation with  
//its constraint validation implementations. 
@Constraint(validatedBy = {ValidDepartmentValidator.class}) 
@Target({ElementType.FIELD, ElementType.PARAMETER}) 
@Retention(value = RetentionPolicy.RUNTIME) 
public @interface ValidDepartment { 
 
    //The message key for validation error message  
    //fails the validation. 
    String message() default  
    "{com.packtpub.rest.validation.deptrule}"; 
    Class<?>[] groups() default {}; 
    Class<? extends Payload>[] payload() default {}; 
} 

As the next step, we need to provide the implementation for the custom validation constraint called ValidDepartmentValidator. Here is the code snippet:

//Other import statements are omitted for brevity 
import javax.validation.ConstraintValidator; 
import javax.validation.ConstraintValidatorContext; 
 
//Defines the logic to validate the constraint 'ValidDepartment' 
//for the object type 'Department' 
public class ValidDepartmentValidator implements 
    ConstraintValidator<ValidDepartment, Department> { 
 
    @Override 
    public void initialize(ValidDepartment constraintAnnotation) { 
    } 
 
    @Override 
    public boolean isValid(Department department,  
        ConstraintValidatorContext context) { 
        //Implementation of isDeptExistsForLoc() is not shown here  
        //to save space. This method return true if the given 
        // department id is found in the database 
        if(isDeptExistsForLoc(department.getDepartmentId(), 
            department.getDepartmentName(),  
            department.getLocationId())) { 
            return false; 
 
        } 
 
        return true; 
    } 
    //Rest of the code goes here 
 
} 

The last step is to define the error message in a resource bundle in order to localize the validation error messages. This file should be added to the root folder with the following name: ValidationMessages.properties. The file contents may look like the following code:

com.packtpub.rest.validation.deptrule= Department already exists  

This feature lets you localize the validation error messages. For example, ValidationMessages_fr.properties contains messages for the French locale. The custom validation constraint for checking a duplicate department entity is ready for use now!

You can apply this constraint on the method parameters or class fields, as shown in the following code snippet:

@POST 
@Path("departments") 
@Consumes(MediaType.APPLICATION_JSON) 
public void create(@ValidDepartment Department entity) { 
    createDepartmentEntity(entity); 
} 
To learn more about Bean Validation, visit the following link: http://beanvalidation.org/. The official tutorial for Bean Validation is available at http://docs.oracle.com/javaee/7/tutorial/partbeanvalidation.htm.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.139.83.151