Tuesday 6 October 2015

Spring Server Side Form Validation Using JSR 303 Annotation

When we accept user inputs in any web application, it become necessary to validate them. We can validate the user input at client side using JavaScript but it’s also necessary to validate them at server side to make sure we are processing valid data incase user has javascript disabled.
Spring MVC Framework supports JSR-303 specs by default and all we need is to add JSR-303 and it’s implementation dependencies in Spring MVC application. Spring also provides @Validator annotation and BindingResult class through which we can get the errors raised by Validator implementation in the controller request handler method.
Step-1

 <!-- Form Validation using Annotations --> 
        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>1.1.0.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>4.1.0.Final</version>
        </dependency>


Step-2

Enabling Spring form validation

Add below entry inside spring web application context
container.

<!-- Enables the Spring MVC @Controller programming model -->
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!-- JSR-303/JSR-349 support will be detected 
    on classpath and enabled automatically -->
    <mvc:annotation-driven/>

</beans>


Step-3
create instance of pojo to be validated and add into model
shown as below

@RequestMapping(value = "/cust/save", method = RequestMethod.GET) public String saveCustomerPage(Model model) { logger.info("Returning custSave.jsp page"); model.addAttribute("ccustomer", new Customer()); return "custSave";
}


Step-4
Apply JSR 303 annotation on pojo to validate it

public class Customer { @Size(min=2, max=30) private String name; @NotEmpty @Email private String email; @NotNull @Min(18) @Max(100) private Integer age; @NotNull private Gender gender; @DateTimeFormat(pattern="MM/dd/yyyy") @NotNull @Past private Date birthday; @Phone private String phone;
}

Above @Phone is custom validator m

Step-5

Bind above pojo(command name) with html form using spring form tag....

<springForm:form method="POST" commandName="ccustomer" action="save.do">


<tr> <td>Name:</td> <td><springForm:input path="name" /></td> <td><springForm:errors path="name" cssClass="error"/></td> </tr> <tr> <td>Email:</td> <td><springForm:input path="email" /></td> <td><springForm:errors path="email" cssClass="error" /></td> </tr>

</springForm:form>


Step-6

message_en.properties

Configure the error message
#application messages for annotations, {ValidationClass}.{modelObjectName}.{field} #the {0} is field name, other fields are in alphabatical order, max and then min  
Size.customer.name=Customer {0} should be between {2} and {1} characters long NotEmpty.customer.email=Email is a required field NotNull.customer.age=Customer {0} should be in years



Step-7
When you submit the form

@RequestMapping(value = "/cust/save.do", method = RequestMethod.POST) public String saveCustomerAction( @Valid @ModelAttribute("ccustomer") Customer customer, BindingResult bindingResult, Model model) { if (bindingResult.hasErrors()) { logger.info("Returning custSave.jsp page"); return "custSave"; } logger.info("Returning custSaveSuccess.jsp page"); model.addAttribute("customer", customer); customers.put(customer.getEmail(), customer); return "custSaveSuccess"; }




Order of message searching................

Size.ccustomer.name -> Size.name -> Size


Step-8
Configuring the resource bundle

<beans:bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<beans:property name="basename" value="classpath:message" /> <beans:property name="defaultEncoding" value="UTF-8" />
</beans:bean>

classpath means
src/main/resurces

message_en.properties -> message.properties
message_jp.properties -> japnese
message_fr.properties ->French

















No comments:

Post a Comment