Custom validator based on Spring Validator interface

Spring provides a Validator interface, which has a validate method where the validation rules are checked. The interface not only supports validation of the web tier, but it can also be used in any tier to validate the data. In case the validation rules fail, the user has to be made aware of it by showing appropriate informative messages. The BindingResult, a child of Errors, holds the validation result bounded by Errors while performing validation on the model in the validate() method. The bounded messages for the errors will be displayed using the <form:errors> tag in the view to make the user aware of them.

Let's add a custom validator in our ReadMyBooks application with the help of the following steps:

  1. Add the validation-api-1.1.0.final.api.jar file in the lib folder of the application.
  2. Create a BookValidator class in the com.packt.ch06.validators package.
  3. The class implements the org.springframework.validation.Validator interface.
  4. Override the supports() method, as shown in the following code:
public class BookValidator implements Validator { 
  public boolean supports(Class<?>book_class) { 
   return book_class.equals(Book.class); 
  } 
} 

The support() method ensures that the object matches the object being validated by the validate() method.

  1. Now, override the validate() method. The validate method has the logic to check whether the data entered by the user in the form is as per the validation rules or not. We will do it by the following three steps:
    1. Set the rules for validation. We will cross-check the following rules:
      • The length of the book's name must be greater than five characters
      • The author's name must not be empty
      • The description must not be empty
      • The description length must be of minimum 10 and maximum 40 characters
      • The ISBN should not be less than 150 characters
      • The price should not be less than 0
      • The publication must not be empty
    2. Write the condition to check the validation rules.
    3. If validation fails, add a message to an instance of errors using the rejectValue () method.

The method using the preceding steps can be written as follows:

public void validate(Object obj, Errors errors) { 
  // TODO Auto-generated method stub 
  Book book=(Book) obj; 
  if (book.getBookName().length() < 5) { 
    errors.rejectValue("bookName", "bookName.required", 
    "Please Enter the book Name"); 
  } 
  if (book.getAuthor().length() <=0) { 
    errors.rejectValue("author", "authorName.required", 
    "Please Enter Author's Name"); 
  } 
  if (book.getDescription().length() <= 0) 
  { 
    errors.rejectValue("description",  
    "description.required", 
    "Please enter book description"); 
  } 
  else if (book.getDescription().length() < 10 ||  
    book.getDescription().length() <  40) { 
    errors.rejectValue("description", "description.length", 
    Please enter description within 40 charaters only"); 
  } 
  if (book.getISBN()<=150l) { 
    errors.rejectValue("ISBN", "ISBN.required", 
    "Please Enter Correct ISBN number"); 
  } 
  if (book.getPrice()<=0 ) { 
    errors.rejectValue("price", "price.incorrect","Please  
      enter a Correct correct price"); 
  } 
  if (book.getPublication().length() <=0) { 
    errors.rejectValue("publication",  
    "publication.required", 
    "Please enter publication "); 
  } 
} 

The Errors interface is used to store the binding information about the validation of the data. The errors.rejectValue() method is one of the very useful methods provided by it, which registers the errors for an object along with their error messages. The following are the available signatures of the rejectValue() method from the Errors interface:

void rejectValue(String field_name, String error_code); 
void rejectValue(String field_name, String error_code,  
String default_message); 
void rejectValue(String field_name, String error_code, 
Object[] error_Args,String default_message); 
  1. Add a data member of type org.springframework.validation.Validator in AddBookController, and annotate it with @Autowired, as follows:
@Autowired 
Validator validator; 
  1. Update the addBook() method of AddController to invoke the validate() method, and check whether the validation error occurred or not. The updated code is as follows:
public ModelAndView addBook(@ModelAttribute("book") Book book, 
BindingResult bindingResult)throws Exception { 
 
  validator.validate(book, bindingResult); 
  if(bindingResult.hasErrors()) 
  { 
    return new ModelAndView("bookForm"); 
  } 
  ModelAndView modelAndView = new ModelAndView(); 
  modelAndView.setViewName("display"); 
  //later on the list will be fetched from the table 
  List<Book>books=new ArrayList(); 
  books.add(book); 
  modelAndView.addObject("book_list",books); 
  modelAndView.addObject("auth_name",book.getAuthor()); 
  return modelAndView; 
} 

The method signature of addBook () should have BindingResult as one of its arguments. The instance of BindingResult has the list of errors that occurred while performing the validation. The hasErrors() method returns true if validation failed on the data members. If hasErrors() returns true, we return the bookForm view, facilitating the user to enter the correct values. In case of no validation violation, the display view will be returned to the Front Controller.

  1. Register BookValidator as a bean in books-servlet.xml, as follows:
<bean id="validator" 
  class="com.packt.ch06.validators.BookValidator"/> 

You can also use @Component instead of the preceding configuration.

  1. The validation violation messages have to be shown to the user by updating the bookForm.jsp file, as shown in the following code:
<tr> 
  <tdwidth="50%"align="right">Name of the Book</td> 
  <tdwidth="50%"align="left"> 
    <form:inputpath="bookName"size="30" /> 
    <font color="red"><form:errors path="bookName" /></font> 
  </td> 
</tr> 

Only the highlighted code has to be added in the bookForm.jsp file to show the message in red color.

The <form:errors> tag is used to display the messages if validation failed. It takes the following syntax:

<form:errors path="name of the data_member"/> 
  1. Update the bookForm.jsp file for all the inputs by specifying the name of the data members as value for the path attribute.
  2. Run the application. Click on the Show form to add new Book link.
  3. Without entering any data in the text fields, submit the form. We will get the form displaying the messages that denote which validation rules are violated, as shown in the following figure:

Even though the code written for the preceding validation is working fine, we are not taking complete advantage of the Spring framework. The invocation of the validate method is explicit, as the framework is not aware to carry out validation implicitly. The @Valid annotation provides information to the framework to perform validation implicitly using custom validators. The framework facilitates binding of the custom validator to WebDataBinder, giving awareness to the framework to use the validate() method.

..................Content has been hidden....................

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