Spring MVC Form Validation Example With Annotation

Spring MVC form can be used to submit user data to web server, then web server logic bean can process those data and return related JSP view page back to the client. But before sending the data to the backend logic bean, it is better to validate the data value first, this can improve server code performance and avoid unnecessary code execution.

Spring MVC provides a form data value validation framework for you to make form data validation easily and quickly. This is better than client-side javascript form value validation because javascript form data validation can not prevent hacker programs invoke backend code directly. This article will tell you how spring implements form data validation.

1. Spring MVC Form Data Validation Architecture.

  1. First, let us look at the spring MVC form validation diagram as below.
  2. You can see there are two components between form views and controller objects. They are Property Editor and Validators.
    spring-mvc-editor-validator-diagram

2. Form Data Object.

  1. The form data object is generally a POJO (plain object java object ) which is used to transfer spring form filed value between form view and controller.
  2. Below java class is just a form data object class this example uses. Each UserAccountDTO class property is mapped to one form submit field ( UserAccountDTO property name is the same as the spring’s form field tag’s path attribute ). For example, the userName property is mapped to the userName form field.

2.1 Form Data Object Definition.

  1. UserAccountDTO.java
    import android.support.annotation.Size;
    
    public class UserAccountDTO {
    
        @NotEmpty
        @Size(min=10, max=30)
        private String userName;
        ......
        @NotNull
        @Past
        private Date birthday;
    
        public String getUserName() {
            return userName;
        }
    
        public void setUserName(String userName) {
            this.userName = userName;
        }
        ......
        public Date getBirthday() {
            return birthday;
        }
    
        public void setBirthday(Date birthday) {
            this.birthday = birthday;
        }
    }

2.2 Use Form Data Object In Controller.

  1. The form data object is usually saved in the spring model attribute with an attribute name.
  2. In this example, the model attribute name is “userAccountData“. Then both JSP view and controller request processing methods can get it by the model attribute name.
  3. To get the form data object instance in the spring MVC controller’s request mapping method, just use @ModelAttribute annotation to annotate the method parameter with the form data object attribute name as below.
    public String registerUserAccount(Model model, @ModelAttribute("userAccountData") @Validated UserAccountDTO userAccountDto, BindingResult result)
  4. To add the form data object in the spring model attribute, just use the model addAttribute method.
    model.addAttribute("userAccountData", userAccountDto);

2.3 Use Form Data Object In JSP.

  1. To get the form data object on the JSP view page, just set the form data object model attribute name in the spring’s form tag modelAttribute attribute value like below.
    <form:form action="${pageContext.request.contextPath}/register_user_account.html" modelAttribute="userAccountData" method="post">
    
        <spring:message code="register_label_user_name" />&nbsp;
        <form:input path="userName"/>&nbsp;
        <form:errors path="userName"/><br/><br/>
    
        ......
    
    </form:form>

3. Form Data Object Property Editor.

3.1 Create Property Editor Java Class.

  1. When users submit data use the spring form, all the data is saved in the form data object properties.
  2. Property Editor is a java class that extends java.beans.PropertyEditorSupport class.
  3. The custom class should override PropertyEditorSupport‘s getAsText and setAsText(String text) method.
  4. This class is useful for none string type form data object properties especially. It can convert the form data value between string type and the object property value real type ( for example Integer, Float, Date, etc).
  5. getAsText(): Get the form data object property value first and then return it’s string format value.
  6. setAsText(String text): Convert the string text value to the property data type and set the converted value to form data object property.
  7. If you do not use property editor for non-string type form data object property such as java.util.Date, it will show error messages like below on the JSP web page.
    Failed to convert property value of type java.lang.String to required type java.util.Date for property birthday;

    spring-do-not-use-form-data-object-property-editor-will-show-errors-for-none-string-type

  8. Below is an example of a custom property editor class. This class will convert property value between String and java.util.Date type. So that although the UserAccountDTO.birthday is a java.util.Date type, you also can convert it to any format string in the JSP Birthday input text box.
  9. And it can also convert the birthday string ( in the specified date format ) you input to java.util.Date type and set the converted Date value to form’s data object’s birthday property (UserAccountDTO.birthday).
    spring-mvc-form-data-object-property-editor-example
  10. Below is the source code of the custom property editor class DateEditor.
    package com.dev2qa.mvc.editorvalidator.editor;
    
    import java.beans.PropertyEditorSupport;
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    public class DateEditor extends PropertyEditorSupport {
        @Override
        public String getAsText() {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
            String ret = sdf.format(new Date());
            Object value = this.getValue();
            if(value!=null)
            {
                if(value instanceof Date) {
                    ret = sdf.format((Date)value);
                }
            }
            return ret;
        }
    
        @Override
        public void setAsText(String text) throws IllegalArgumentException {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
            Date date = null;
            try {
                date = sdf.parse(text);
            }catch(ParseException e){
                date = new Date();
            }finally
            {
                this.setValue(date);
            }
        }
    }

3.2 Use Property Editor.

  1. To use this property editor, you need to first add a method in the controller manually and annotated it with @InitBinder annotation. And then register the custom editor in the method.
  2. The method name is not fixed, but the method input parameter type should be WebDataBinder. The argument of @InitBinder annotation is the form modelAttribute name.
    @InitBinder("userAccountData")
    public void initBinder(WebDataBinder binder){
        binder.registerCustomEditor(Date.class, new DateEditor());
    }

4. Form Data Object Property Validator.

4.1 Default Validator LocalValidatorFactoryBean.

  1. Form data object property value validator is used to validate data value by rules. Spring provides a default data value validator bean LocalValidatorFactoryBean which can be used to validate most of the data value.
  2. To use LocalValidatorFactoryBean, you need to first register it in the application context java-config class ( Because we use java class to configure spring MVC, not XML-based bean configuration ).
    @Bean(name="validator")
    public LocalValidatorFactoryBean validator(){
        return new LocalValidatorFactoryBean();
    }
  3. Then @Autowired the validator bean in spring MVC controller class.
    @Autowired
    private LocalValidatorFactoryBean validator;
  4. Please remember do not need to add the default validator in the controller’s initBinder method, it will take effect automatically.
    @InitBinder("userAccountData")
    public void initBinder(WebDataBinder binder){
        /* The default validator do not need to set. It can take effect automatically by default. 
         * */
        //binder.setValidator(validator);
        binder.registerCustomEditor(Date.class, new DateEditor());
    }
  5. Then add the @Validated annotation before the form data object (userAccountDto) in the controller @RequestMapping method. Now spring framework will validate user submit form data object properties automatically.
    @RequestMapping(method=RequestMethod.POST)
    public String registerUserAccount(Model model, @ModelAttribute("userAccountData") @Validated UserAccountDTO userAccountDto, BindingResult result) {
        String ret = "register_user_account_success";
        //Do not invoke the validator.validate method here, this will cause error messages show twice in the jsp web page like below picture.
            // validator.validate(userAccountDto, result);
        if(result.hasErrors()){
            ret = "register_user_account_form";
        }
        return ret;
    }
    
    

    spring-form-data-validate-show-error-messages-twice

4.2 Custom Form Data Value Validator Class.

  1. Besides the default validator, you can also create your own custom spring MVC form data validator by implement org.springframework.validation.Validator interface. Then override it’s supports and validate method.
    public class UserAccountValidator implements Validator {
    
          ......
    
    }
  2. After that, you should config the custom validator class as spring bean in the spring java-config class.
    @Bean(name="customUserAccountValidator")
    public Validator customUserAccountValidator(){
        return new UserAccountValidator();
    }
  3. For custom validator, you should add the custom validator spring bean in the controller’s @InitBind method use binder.setValidator(), otherwise it will not take effect.
    @InitBinder("userAccountData")
    public void initBinder(WebDataBinder binder){
    
       binder.setValidator(customUserAccountValidator);
    
       binder.registerCustomEditor(Date.class, new DateEditor());
    
    }
  4. Annotate the model attribute parameter in the controller’s @RequestMapping method with @Validated annotation, do not call the customer validator’s validate method in the method, otherwise, the error messages will show twice on the JSP web page also.

4.3 Define Form Property Validator Rules With Annotation.

  1. When creating the property validator, you need to specify validation rules in UserAccountDTO.java class. All the rules are defined with annotations (@NotEmpty, @Size, @Past, @Min, @Max, @NotNull, etc).  The annotation meaning is straightforward.
    public class UserAccountDTO {
    
        @NotEmpty
        @Size(min=10, max=30)
        private String userName;
    
        @NotEmpty
        @Size(min=8, max=30)
        private String password;
    
        @NotEmpty
        @Email(message="Email format is not correct.")
        private String email;
    
        @NotNull
        @Min(0) @Max(100)
        private Integer age;
    
        @NotNull
        @Past
        private Date birthday;
    
        @NotNull
        @Min(1000) @Max(10000)
        private Float salary;
    
        ......
    }

4.4 Define Form Property Validator Error Message In Properties File.

  1. Create the file errors.properties in the src/main/resources/config folder. If the config folder does not exist then create it manually. It contains all the form object property validation error messages.
  2. It’s content are key value pairs. The key format is Validator_Rule_Annotation.Model_Attribute_Name.Object_Property_Name, for example (Size.userAccountData.userName).
  3. Below is an example of the file content.
    Size.userAccountData.userName=User name value should has at least 10 characters and at most 30 characters.
  4. After creating this file, you also need to add it in the message source bean base name with the below code.
    ReloadableResourceBundleMessageSource ret = new ReloadableResourceBundleMessageSource();
    /* Set the base name for the messages and validator errors properties file.
      All the messages.perperties file are saved in src/main/resources/config folder
      While all validate errors message are saved in src/main/resources/config/errors.properties file. */
    ret.setBasenames("classpath:config/messages","classpath:config/errors");
    

4.5 Define Custom Validator Error Message.

  1. If you use a custom validator, you can define error messages in the errors.properties file also and then use that message key in the custom validator validate method as below.
    public void validate(Object target, Errors errors) {
        
        UserAccountDTO userAccount = (UserAccountDTO) target;
        ValidationUtils.rejectIfEmptyOrWhitespace(errors, "userName", "Size.userAccountData.userName");
        errors.rejectValue("age", "age_too_old");
    }

5. Spring MVC Form Validation Example.

  1. The below image uses the default spring form property validator.
    spring-form-validation-example-use-default-spring-validator
  2. The below image uses a custom spring form property validator.
    use-custom-spring-form-property-validator-web-page

5.1 Example Source Files.

spring-form-validation-example-source-files

5.2 Spring Context Bean Configuration Java File.

  1. ContextConfig.java
    package com.dev2qa.mvc.editorvalidator.config;
    
    import org.springframework.context.MessageSource;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.support.ReloadableResourceBundleMessageSource;
    import org.springframework.validation.Validator;
    import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
    import org.springframework.web.servlet.config.annotation.EnableWebMvc;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
    import org.springframework.web.servlet.view.InternalResourceViewResolver;
    
    import com.dev2qa.mvc.editorvalidator.validator.UserAccountValidator;
    
    @EnableWebMvc
    @Configuration
    @ComponentScan(basePackages="com.dev2qa.mvc")
    public class ContextConfig extends WebMvcConfigurerAdapter {
    
        /* Create a MessageSource bean to show message from message files, for i18n purpose. */
        @Bean(name = "messageSource")
        public MessageSource getMessageSource() {
            ReloadableResourceBundleMessageSource ret = new ReloadableResourceBundleMessageSource();
          
          /* Set the base name for the messages and validator errors properties file. 
             All the messages.perperties file are saved in src/main/resources/config folder
             While all validate errors message are saved in src/main/resources/config/errors.properties file. */
            ret.setBasenames("classpath:config/messages","classpath:config/errors");
    
            ret.setCacheSeconds(1);
    
            ret.setUseCodeAsDefaultMessage(true);
    
            ret.setDefaultEncoding("utf-8");
    
            return ret;
        }
    
        /* Used to render jsp pages to client. */
        @Bean(name = "jspViewResolver")
        public InternalResourceViewResolver getJspViewResolver() {
    
            InternalResourceViewResolver ret = new InternalResourceViewResolver();
            // The prefix of the Controller's RequestMapping method returned string.
            ret.setPrefix("/WEB-INF/view/");
            // The suffix of the Controller's RequestMapping method returned string.
            ret.setSuffix(".jsp");
            ret.setOrder(1);
            return ret;
    
        }
    
        /* LocalValidatorFactoryBean will validate annotated DTO's properties by the property annotation automatically. */
        @Bean(name="validator")
        public LocalValidatorFactoryBean validator(){
            return new LocalValidatorFactoryBean();
        }
    
        /* This is the custom user account validator bean. */
        @Bean(name="customUserAccountValidator")
        public Validator customUserAccountValidator(){
            return new UserAccountValidator();
        }
    }

5.3 Spring Dispatcher Servlet Definition Java File.

  1. ContextDispatcherServlet.java
    package com.dev2qa.mvc.editorvalidator.config;
    
    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRegistration;
    
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.WebApplicationInitializer;
    import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
    import org.springframework.web.servlet.DispatcherServlet;
    
    @Configuration
    public class ContextDispatcherServlet implements WebApplicationInitializer {
    
        @Override
        public void onStartup(ServletContext servletContext) throws ServletException {
    
            AnnotationConfigWebApplicationContext dispatcherServletContext = new AnnotationConfigWebApplicationContext();
    
            dispatcherServletContext.register(ContextConfig.class);
    
            DispatcherServlet dispatcherServlet = new DispatcherServlet(dispatcherServletContext);
    
            // Create a servlet dynamically.
            ServletRegistration.Dynamic dispatcher = servletContext.addServlet("DispatcherServlet", dispatcherServlet);
    
            dispatcher.setLoadOnStartup(1);
    
            // Add servlet mapping url. All url end with .html will be processed by this servlet.
            dispatcher.addMapping("*.html");
        }
    }

5.4 Form Validation Controller.

  1. RegisterUserController.java
    package com.dev2qa.mvc.editorvalidator.controller;
    
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.List;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.validation.BindingResult;
    import org.springframework.validation.Validator;
    import org.springframework.validation.annotation.Validated;
    import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
    import org.springframework.web.bind.WebDataBinder;
    import org.springframework.web.bind.annotation.InitBinder;
    import org.springframework.web.bind.annotation.ModelAttribute;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    
    import com.dev2qa.mvc.editorvalidator.dto.UserAccountDTO;
    import com.dev2qa.mvc.editorvalidator.editor.AgeEditor;
    import com.dev2qa.mvc.editorvalidator.editor.DateEditor;
    import com.dev2qa.mvc.editorvalidator.editor.SalaryEditor;
    import com.dev2qa.mvc.editorvalidator.validator.UserAccountValidator;
    
    /* http://localhost:8080/SpringMVCEditorValidator/register_user_account.html will invoke this controller.*/
    @Controller
    @RequestMapping("/register_user_account.html")
    public class RegisterUserController {
    
        /* Autowire validator.*/
        @Autowired
        private LocalValidatorFactoryBean validator;
    
        /* Autowire custom user account validator.*/
        @Autowired
        private Validator customUserAccountValidator;
    
        // Model attribute key.
        public static final String ATTR_USER_ACCOUNT_DATA = "userAccountData";
    
        /* @InitBinder annotated method will register custom editor and set Validator to the model attribute by the attribute name. */
        @InitBinder(ATTR_USER_ACCOUNT_DATA)
        public void initBinder(WebDataBinder binder){
          
          /* The default validator do not need to set. It can take effect automatically by default. 
           * If set the default validator here, the web page will show two same error messages.
           * */
            //binder.setValidator(validator);
    
            // The custom validator need to be set or add here to take effect.
            binder.setValidator(customUserAccountValidator);
    
            //binder.addValidators(customUserAccountValidator);
    
            /* Register form object java.util.Date, Integer and Float type property editor. 
               The first parameter is property data type class, the second parameter is related property editor instance object.
            */
            binder.registerCustomEditor(Date.class, new DateEditor());
            binder.registerCustomEditor(Integer.class, new AgeEditor());
            binder.registerCustomEditor(Float.class, new SalaryEditor());
        }
    
        /* When request the url in GET method. */
        @RequestMapping(method=RequestMethod.GET)
        public String showUserAccountRegistrPage(Model model) {
    
            UserAccountDTO userAccountDto = new UserAccountDTO();
    
            model.addAttribute(ATTR_USER_ACCOUNT_DATA, userAccountDto);
    
            return "register_user_account_form";
        }
    
        /* When request the url ( http://localhost:8080/SpringMVCEditorValidator/register_user_account.html) in POST method. */
        @RequestMapping(method=RequestMethod.POST)
        public String registerUserAccount(Model model, @ModelAttribute(ATTR_USER_ACCOUNT_DATA) @Validated UserAccountDTO userAccountDto, BindingResult result) {
    
            String ret = "register_user_account_success";
    
            // Do not need validate here, because have add the validator in the @InitBinder method. Otherwise the error messages will be shown twice in jsp page.
            // validator.validate(userAccountDto, result);
            // customUserAccountValidator.validate(userAccountDto, result);
            if(result.hasErrors()){
                ret = "register_user_account_form";
            }
    
            return ret;
        }
    }

5.5 Form Data Object Java File.

  1. UserAccountDTO.java
    package com.dev2qa.mvc.editorvalidator.dto;
    
    import java.util.Date;
    
    import javax.validation.constraints.Max;
    import javax.validation.constraints.Min;
    import javax.validation.constraints.NotNull;
    import javax.validation.constraints.Past;
    import javax.validation.constraints.Size;
    
    import org.hibernate.validator.constraints.Email;
    import org.hibernate.validator.constraints.NotEmpty;
    
    public class UserAccountDTO {
    
        @NotEmpty
        @Size(min=10, max=30)
        private String userName;
    
        @NotEmpty
        @Size(min=8, max=30)
        private String password;
    
        @NotEmpty
        @Email(message="Email format is not correct.")
        private String email;
    
        @NotNull
        @Min(0) @Max(100)
        private Integer age;
    
        @NotNull
        @Past
        private Date birthday;
    
        @NotNull
        @Min(1000) @Max(10000)
        private Float salary;
    
        public String getUserName() {
            return userName;
        }
    
        public void setUserName(String userName) {
            this.userName = userName;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        public String getEmail() {
            return email;
        }
    
        public void setEmail(String email) {
            this.email = email;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        public Date getBirthday() {
            return birthday;
        }
    
        public void setBirthday(Date birthday) {
            this.birthday = birthday;
        }
    
        public Float getSalary() {
            return salary;
        }
    
        public void setSalary(Float salary) {
            this.salary = salary;
        }
    }

5.6 Form Data Object Property Editor.

  1. AgeEditor.java
    package com.dev2qa.mvc.editorvalidator.editor;
    
    import java.beans.PropertyEditorSupport;
    
    public class AgeEditor extends PropertyEditorSupport {
    
        @Override
        public String getAsText() {
            String ret = "0";
            Object currValue = this.getValue();
            if(currValue!=null)
            {
                ret = currValue.toString();
            }
            return ret;
        }
    
        @Override
        public void setAsText(String text) throws IllegalArgumentException {
            int age = 0;
            try{
                age = Integer.parseInt(text);
            }catch(NumberFormatException e){
                age = 0;
            }finally {
                this.setValue(age);
            }
        }
    }
  2. DateEditor.java
    package com.dev2qa.mvc.editorvalidator.editor;
    
    import java.beans.PropertyEditorSupport;
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    public class DateEditor extends PropertyEditorSupport {
    
        @Override
        public String getAsText() {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
    
            String ret = sdf.format(new Date());
    
            Object value = this.getValue();
    
            if(value!=null)
            {
                if(value instanceof Date) {
                    ret = sdf.format((Date)value);
                }
            }
    
            return ret;
        }
    
        @Override
        public void setAsText(String text) throws IllegalArgumentException {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
            Date date = null;
            try {
                date = sdf.parse(text);
            }catch(ParseException e){
                date = new Date();
            }finally
            {
                this.setValue(date);
            }
        }
    }
  3. SalaryEditor.java
    package com.dev2qa.mvc.editorvalidator.editor;
    
    import java.beans.PropertyEditorSupport;
    
    public class SalaryEditor extends PropertyEditorSupport {
    
        @Override
        public String getAsText() {
            String ret = "0";
            Object currValue = this.getValue();
            if(currValue!=null)
            {
                ret = currValue.toString();
            }
            return ret;
        }
    
        @Override
        public void setAsText(String text) throws IllegalArgumentException {
            float salary = 0;
            try{
                salary = Float.parseFloat(text);
            }catch(NumberFormatException e){
                salary = 0;
            }finally {
                this.setValue(salary);
            }
        }
    }

5.7 Custom Form Data Object Property Validator.

  1. UserAccountValidator.java
    package com.dev2qa.mvc.editorvalidator.validator;
    
    import org.springframework.validation.Errors;
    import org.springframework.validation.ValidationUtils;
    import org.springframework.validation.Validator;
    
    import com.dev2qa.mvc.editorvalidator.dto.UserAccountDTO;
    
    public class UserAccountValidator implements Validator {
    
        /* Verify that the @ModelAttribute object is instance of UserAccountDTO class. 
         * Return true means can validate the class object.
         * */
        @Override
        public boolean supports(Class<?> clazz) {
            boolean ret = clazz.equals(UserAccountDTO.class);
            return ret;
        }
    
        /* All the custom validation process are performed in this method. */
        @Override
        public void validate(Object target, Errors errors) {
    
            UserAccountDTO userAccount = (UserAccountDTO) target;
    
            // Validate userName property.
            ValidationUtils.rejectIfEmptyOrWhitespace(errors, "userName", "Size.userAccountData.userName");
    
            // Validate password property.
            ValidationUtils.rejectIfEmptyOrWhitespace(errors, "password", "Size.userAccountData.password");
    
            // Validate age property.
            if(userAccount.getAge() > 85) {
                errors.rejectValue("age", "age_too_old");
            }
        }
    }

5.8 Message Files.

All the message properties files are saved in the src/main/resources/config folder.

  1. errors.properties
    Size.userAccountData.userName=User name value should has at least 10 characters and at most 30 characters.
    Size.userAccountData.password=Password value size should between 8 to 30 characters.
    
    NotEmpty.userAccountData.email=Email can not be empty.
    Min.userAccountData.age=Age value can not smaller than 0.
    Max.userAccountData.age=Age value can not bigger than 100.
    Past.userAccountData.birthday=Birthday should be past date.
    Min.userAccountData.salary=Salary minimum value is 1000.
    Max.userAccountData.salary=Salary maximum value is 10000.
    
    age_too_old=You are too old.
  2. messages.properties
    register_user_title=User Account Register Page
    register_user_desc=Input user account data to register.
    register_label_user_name=User Name:
    register_label_password=Password:
    register_label_email=Email:
    register_label_age=Age:
    register_label_birthday=Birthday:
    register_label_salary=Salary:

5.9 JSP File.

  1. register_user_account_form.jsp
    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
    <%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
    <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
        <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title><spring:message code="register_user_title" /></title>
    </head>
    <body>
        <h3><spring:message code="register_user_desc" /></h3>
    
        <form:form action="${pageContext.request.contextPath}/register_user_account.html" modelAttribute="userAccountData" method="post">
    
            <spring:message code="register_label_user_name" />&nbsp;
            <form:input path="userName"/>&nbsp;<br/>
            <font color=red><form:errors path="userName"/></font><br/><br/>
    
            <spring:message code="register_label_password" />&nbsp;
            <form:password path="password"/>&nbsp;<br/>
            <font color=red><form:errors path="password"/></font><br/><br/>
    
            <spring:message code="register_label_email" />&nbsp;
            <form:input path="email"/>&nbsp;<br/>
            <font color=red><form:errors path="email"/></font><br/><br/>
    
            <spring:message code="register_label_age" />&nbsp;
            <form:input path="age"/>&nbsp;<br/>
            <font color=red><form:errors path="age"/></font><br/><br/>
    
            <spring:message code="register_label_birthday" />&nbsp;
            <form:input path="birthday"/>&nbsp;<br/>
            <font color=red><form:errors path="birthday"/></font><br/><br/>
    
            <spring:message code="register_label_salary" />&nbsp;
            <form:input path="salary"/>&nbsp;<br/>
            <font color=red><form:errors path="salary"/></font><br/><br/>
    
            <input type="submit" value="Register"/>
    
        </form:form>
    
    </body>
    </html>

5.10 pom.xml.

  1. pom.xml.
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>org.springframework.samples.service.service</groupId>
        <artifactId>SpringMVCEditorValidator</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <packaging>war</packaging>
    
        <!-- Spring framework used constants variable  -->
        <properties>
            <spring.version>5.0.0.BUILD-SNAPSHOT</spring.version>
            <servlet.api.version>3.1.0</servlet.api.version>
        </properties>
    
    
        <repositories>
            <!-- This repository is where the spring framework dependencies jar file download. -->
            <repository>
                <id>spring-snapshots</id>
                <name>Spring Snapshots</name>
                <url>https://repo.spring.io/libs-snapshot</url>
                <snapshots>
                    <enabled>true</enabled>
                </snapshots>
            </repository>
        </repositories>
    
        <dependencies>
            <!-- Below are the basic spring container dependencies library. -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>${spring.version}</version>
            </dependency>
    
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-beans</artifactId>
                <version>${spring.version}</version>
            </dependency>
    
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifactId>
                <version>${spring.version}</version>
            </dependency>
    
            <!-- Below dependency is used for spring mvc framework. -->
            <!-- 
            <dependency>
                 <groupId>org.springframework</groupId>
                 <artifactId>spring-web</artifactId>
                 <version>${spring.version}</version>
              </dependency>
              -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>${spring.version}</version>
            </dependency>
    
            <!-- Below dependency is used for servlet and jsp. -->
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <version>${servlet.api.version}</version>
                <scope>provided</scope>
            </dependency>
    
            <dependency>
                <groupId>javax.servlet.jsp</groupId>
                <artifactId>javax.servlet.jsp-api</artifactId>
                <version>2.3.1</version>
                <scope>provided</scope>
            </dependency>
    
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>jstl</artifactId>
                <version>1.2</version>
            </dependency>
    
            <dependency>
                <groupId>taglibs</groupId>
                <artifactId>standard</artifactId>
                <version>1.1.2</version>
            </dependency>
    
            <dependency>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-validator</artifactId>
                <version>5.0.1.Final</version>
            </dependency>
    
            <dependency>
                <groupId>javax.validation</groupId>
                <artifactId>validation-api</artifactId>
                <version>1.1.0.Final</version>
            </dependency>
    
        </dependencies>
    
        <build>
            <finalName>spring-custom-editor-validator-example</finalName>
            <plugins>
                <!-- Because this project do not use web.xml so need below settings. -->
                <plugin>
                    <artifactId>maven-war-plugin</artifactId>
                    <version>2.3</version>
                    <configuration>
                        <failOnMissingWebXml>false</failOnMissingWebXml>
                    </configuration>
                </plugin>
    
                <plugin>
                    <groupId>org.apache.tomcat.maven</groupId>
                    <artifactId>tomcat7-maven-plugin</artifactId>
                    <version>2.2</version>
                    <configuration>
                        <username>tomcat</username>
                        <password>tomcat</password>
                        <!-- update true will override the existing deployed war file in tomcat -->
                        <update>true</update>
                    </configuration>
                </plugin>
    
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.7.0</version>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                    </configuration>
                </plugin>
    
            </plugins>
        </build>
    
    </project>

2 thoughts on “Spring MVC Form Validation Example With Annotation”

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.