Spring MVC 表单验证不适用于嵌套的复杂类型

Posted

技术标签:

【中文标题】Spring MVC 表单验证不适用于嵌套的复杂类型【英文标题】:Spring MVC form validation does't work for nested complex types 【发布时间】:2016-09-28 15:46:17 【问题描述】:

我正在实现一个带有表单验证的示例 Spring MVC 表单。我有一个复杂类型 Address 作为 Student 表单 bean 的 bean 属性。我已经为Address bean 属性添加了表单验证@NotEmpty。但同样没有反映在 UI 中。但表单验证适用于 Student 表单 bean 的其他原始类型。

因此,验证对于Student 表单bean 非常有效,但不适用于AddressStudent 表单bean 中的嵌套复杂类型。

我正在尝试了解原因和解决方法。

春季版 4.0+。 休眠验证器 api:5.2.4

StudentPOJO:

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;
    

AddressPOJO:

包 com.xyz.form.beans; 导入 org.hibernate.validator.constraints.NotEmpty; 导入 com.xyz.validators.LongNotEmpty; 公共类地址 @不是空的 私人弦乐屋No; @不是空的 私人弦街; @不是空的 私有字符串区域; @不是空的 私人字符串城市; @LongNotEmpty 私人长针; 公共字符串 getHouseNo() 归还屋号; 公共无效setHouseNo(字符串houseNo) this.houseNo = houseNo; 公共字符串 getStreet() 返回街道; 公共无效 setStreet(字符串街道) this.street = 街道; 公共字符串 getArea() 返回区; 公共无效setArea(字符串区域) this.area = 面积; 公共字符串 getCity() 返回城市; 公共无效setCity(字符串城市) this.city = 城市; 公共长 getPin() 返回销; 公共无效setPin(长针) 这个.pin = pin;

Student控制器:

@RequestMapping(value = "/newStudentDetails.do", method = RequestMethod.POST) public ModelAndView newStudentDetails( @Valid @ModelAttribute("student") com.xyz.form.beans.Student studentFormBean, 绑定结果绑定结果) if (bindingResult.hasErrors()) 返回新的 ModelAndView("newStudentPage"); 学生 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"); 返回mav;

谢谢, 维斯瓦纳特

【问题讨论】:

你很高兴不包括相关的类......将它们添加到你的问题中。 请找到添加的代码。让知道您是否有解决方案。提前致谢。 嵌套对象需要 @Valid 注释,如 JSR-303 规范中所述。所以把@Valid放在StudentAddress字段上。 完美运行。非常感谢。 【参考方案1】:

您需要使用@Valid 注释您的复杂类型。 This is the reference(引用here)

【讨论】:

【参考方案2】:

嗨,让我们试试用@ModelAttribute("student") @Valid com.xyz.form.beans.Student studentFormBean 代替@Valid @ModelAttribute("student")

【讨论】:

【参考方案3】:

对于嵌套的复杂类型,您必须激活直接字段访问。如下所示:

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

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

【讨论】:

以上是关于Spring MVC 表单验证不适用于嵌套的复杂类型的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET MVC 验证不适用于引导模式

Asp.Net MVC 5 Jquery 验证不适用于带有提交事件的 ajax 帖子,显示为有效表单

Spring 3 @NumberFormat 不适用于表单:输入标签

@Valid 表单验证不适用于 Thymeleaf Spring Boot

使用 DirtiesContext 注释重新加载 Spring 应用程序不适用于嵌套类

使用休眠验证器的 Spring mvc 表单验证