Spring MVC form validation does't work for nested complex types

spring mvc validation example with annotation
spring mvc form validation example
spring mvc validation error messages
spring validation example mkyong
spring boot form validation
spring boot validation annotations
spring mvc custom validation
spring 5 validation

I am implementing a sample Spring MVC Form with Form Validation. I have a complex type Address as bean property for Student form bean. And I have added form validation @NotEmpty for Address bean properties. But the same is not reflecting in the UI. But form validation works for other primitive types of Student form bean.

So, Validation works perfectly for Student form bean but not for nested complex types like Address within Student form bean.

I am trying understand the reason and a fix.

Spring version 4.0+. Hibernate Validator api:5.2.4

Student POJO:

package com.xyz.form.beans;

import java.util.Date;
import java.util.List;

import javax.validation.constraints.Past;
import javax.validation.constraints.Size;

import org.hibernate.validator.constraints.NotEmpty;

import com.xyz.validators.DateNotEmpty;
import com.xyz.validators.ListNotEmpty;

public class Student {
    @Size(min = 2, max = 30)
    private String firstName;
    @Size(min = 2, max = 30)
    private String lastName;
    @NotEmpty
    private String gender;
    @DateNotEmpty
    @Past
    private Date DOB;
    private String email;
    private String mobileNumber;
    @ListNotEmpty
    private List<String> courses;
    private Address address;

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public Date getDOB() {
        return DOB;
    }

    public void setDOB(Date dOB) {
        DOB = dOB;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getMobileNumber() {
        return mobileNumber;
    }

    public void setMobileNumber(String mobileNumber) {
        this.mobileNumber = mobileNumber;
    }

    public List<String> getCourses() {
        return courses;
    }

    public void setCourses(List<String> courses) {
        this.courses = courses;
    }
}

Address POJO:


    package com.xyz.form.beans;

    import org.hibernate.validator.constraints.NotEmpty;

    import com.xyz.validators.LongNotEmpty;

    public class Address {
        @NotEmpty
        private String houseNo;
        @NotEmpty
        private String street;
        @NotEmpty
        private String area;
        @NotEmpty
        private String city;
        @LongNotEmpty
        private Long pin;

        public String getHouseNo() {
            return houseNo;
        }

        public void setHouseNo(String houseNo) {
            this.houseNo = houseNo;
        }

        public String getStreet() {
            return street;
        }

        public void setStreet(String street) {
            this.street = street;
        }

        public String getArea() {
            return area;
        }

        public void setArea(String area) {
            this.area = area;
        }

        public String getCity() {
            return city;
        }

        public void setCity(String city) {
            this.city = city;
        }

        public Long getPin() {
            return pin;
        }

        public void setPin(Long pin) {
            this.pin = pin;
        }
    }

Student Controller:



    @RequestMapping(value = "/newStudentDetails.do", method = RequestMethod.POST)
        public ModelAndView newStudentDetails(
                @Valid @ModelAttribute("student") com.xyz.form.beans.Student studentFormBean,
                BindingResult bindingResult) {
            if (bindingResult.hasErrors()) {
                return new ModelAndView("newStudentPage");
            }
            Student studentDto = new Student();
            studentDto.setFirstName(studentFormBean.getFirstName());
            studentDto.setLastName(studentFormBean.getLastName());
            studentDto.setGender(studentFormBean.getGender());
            studentDto.setDOB(new Date(studentFormBean.getDOB().getTime()));
            studentDto.setEmail(studentFormBean.getEmail());
            studentDto.setMobileNumber(studentFormBean.getMobileNumber());
            StringBuilder sb = new StringBuilder();
            sb.append(studentFormBean.getAddress().getHouseNo() + ", ");
            sb.append(studentFormBean.getAddress().getStreet() + ", ");
            sb.append(studentFormBean.getAddress().getArea() + ", ");
            sb.append(studentFormBean.getAddress().getCity() + "-");
            sb.append(studentFormBean.getAddress().getPin());
            studentDto.setAddress(sb.toString());
            studentDto.setCourses(studentFormBean.getCourses());
            studentDao.createStudent(studentDto);
            ModelAndView mav = new ModelAndView("newStudentSuccess");
            return mav;
        }

Thanks, Viswanath

You need to annotate your complex types with @Valid. This is the reference (which references here)

Spring Validation Example - Spring MVC Form Validator, Validation and Submission of a form is an important aspect of a web application. In this tutorial, we will show how to validate the form fields of a� To validate the model in Spring MVC, let's create a controller with a /user POST mapping that receives a NewUserForm object annotated with @Valid and verifies whether there are any validation errors: @Controller. public class NewUserController {. @GetMapping ( "/user") public String loadFormPage(Model model) {.

Hi lets try @ModelAttribute("student") @Valid com.xyz.form.beans.Student studentFormBean in place of @Valid @ModelAttribute("student")

Getting Started, In Spring MVC, Validator interface can be used to validate all fields of a form. We can configure it within a controller class through the @InitBinder� Spring MVC Form Validation : Here we are going to validate registration form with different fields like firstName, lastName, age, email by using simple spring validation framework.

For nested complex types, you have to activate the direct field access. Just like below:

@org.springframework.web.bind.annotation.ControllerAdvice
public class ControllerAdvice {

    @InitBinder
    public void initBinder(WebDataBinder webDataBinder) {
        webDataBinder.initDirectFieldAccess();
    }

Spring MVC Form Validation Example with Bean Validation API, Generally, when we need to validate user input, Spring MVC offers we'll do just that – we'll create a custom validator to validate a form with a� Spring MVC will validate the model object annotated by the @Valid annotation after binding its properties with inputs from JSP form that uses Spring’s form tags. Any constraint violations will be exposed as errors in the BindingResult object, thus we can check the violation in the controller’s method like this: 1 2

Spring MVC Form Validation Example, If any error is detected you can again render the form view to let user correct it's input. If there is no error found then result.hasErrors() will return false, then you can� Spring MVC form validation Till now our example application is able to display form, and receiving submitted form with filled values. In real life application, user’s will make lots of mistake in filling forms. Validation should always be on client side, but to protect data integrity you should also validate data on server side as well.

Spring MVC 4, Does the class have to be filled manually with the values from the user input, and then passed to the validator? I am confused about the cleanest and best way to� I am following this guide to use Spring Form Validation but I cannot get the form to validate in my own program. I follow everything exactly how it's presented in the guide it just doesn't work in my application. I used Spring Tools Suite and downloaded the sample application to see if it actually works and it does.

Spring MVC Custom Validation, in28Minutes is creating amazing learning solutions for Java, Spring Boot, Implementing Form Duration: 21:02 Posted: Jan 23, 2016 spring-webmvc 4.2.4.RELEASE: Spring Web MVC. spring-test 4.2.4.RELEASE: Spring TestContext Framework. javax.servlet-api 3.0.1 Java Servlet API; hibernate-validator 5.2.4.Final: Hibernate's Bean Validation (JSR-303) reference implementation. junit 4.12: JUnit is a unit testing framework for Java, created by Erich Gamma and Kent Beck. JDK 1.8

Comments
  • And you happily don't include the classes concerned... Add them to your question.
  • Please find the code added. Let know if you have a solution. Thanks in advance.
  • Nested objects require a @Valid annotation as expressed in the JSR-303 spec. So put @Valid on the Address field in Student.
  • Perfectly works. Thanks a ton.