当前位置: 首页 > 知识库问答 >
问题:

Spring MVC复杂bean绑定

陶健
2023-03-14

我有传输对象,包含两个bean:学生和用户。

@Entity
@Table(name = "student")
public class Student implements Serializable {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(name = "name")
private String name;

@Column(name = "middleName")
private String middleName;

@Column(name = "surname")
private String surname;

@ManyToOne
@JoinColumn(name = "idSpeciality")
private Speciality speciality;

public Long getId() {
    return id;
}

public void setId(Long id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getMiddleName() {
    return middleName;
}

public void setMiddleName(String middleName) {
    this.middleName = middleName;
}

public String getSurname() {
    return surname;
}

public void setSurname(String surname) {
    this.surname = surname;
}

public Speciality getSpeciality() {
    return speciality;
}

public void setSpeciality(Speciality speciality) {
    this.speciality = speciality;
}

}

@Entity
@Table(name = "users")
public class User implements Serializable {

@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(name = "email")
private String email;

@Column(name = "password")
private String password;

@Transient
private String passwordConfirm;

@ManyToMany
@JoinTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id"))
private Set<Role> role;

public String getPasswordConfirm() {
    return passwordConfirm;
}

public void setPasswordConfirm(String passwordConfirm) {
    this.passwordConfirm = passwordConfirm;
}

public Set<Role> getRole() {
    return role;
}

public void setRole(Set<Role> roles) {
    this.role = roles;
}

public Long getId() {
    return id;
}

public void setId(Long id) {
    this.id = id;
}

public String getEmail() {
    return email;
}

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

public String getPassword() {
    return password;
}

public void setPassword(String password) {
    this.password = password;
}

}

传输对象:

public class RegistrationTO implements Serializable{

private User user;

private Student student;

public RegistrationTO() {
    user = new User();
    student = new Student();
    student.setSpeciality(new Speciality());
}

public User getUser() {
    return user;
}

public void setUser(User user) {
    this.user = user;
}

public Student getStudent() {
    return student;
}

public void setStudent(Student student) {
    this.student = student;
}

}

我还有注册页面和表格:

<form:form method="POST" modelAttribute="registrationForm" commandName="registrationForm" class="col s12">
    <input type="hidden" name="${_csrf.parameterName}"
           value="${_csrf.token}" />

    <div class="row">
            <div class="input-field col s12 ${status.error ? 'has-error' : ''}">
                <i class="material-icons prefix">email</i>
                <form:input type="email" path="user.email" class="validate"
                            placeholder="Email" id="loginInput" autofocus="true" />
                <form:errors path="user.email"></form:errors>
                <label for="loginInput">Email</label>
            </div>
    </div>

    <div class="row">
        <div class="input-field col s6 ${status.error ? 'has-error' : ''}">
            <i class="material-icons prefix">vpn_key</i>
            <form:input type="password" path="user.password" class="form-control"
                        placeholder="Пароль" id="passwordInput"></form:input>
            <form:errors path="user.password"></form:errors>
            <label for="passwordInput">Пароль</label>
        </div>

        <div class="input-field col s6 ${status.error ? 'has-error' : ''}">
            <form:input type="password" path="user.passwordConfirm" class="form-control"
                        placeholder="Повторите пароль" id="secondPasswordInput"></form:input>
            <form:errors path="user.passwordConfirm"></form:errors>
            <label for="secondPasswordInput">Повторите пароль</label>
        </div>
    </div>

    <div class="row">
        <div class="input-field col s4 ${status.error ? 'has-error' : ''}">
            <i class="material-icons prefix">account_circle</i>
            <form:input type="text" path="student.surname" class="validate"
                        placeholder="Фамилия" id="stSurnameInput"></form:input>
            <form:errors path="student.surname"></form:errors>
            <label for="stSurnameInput">Фамилия</label>
        </div>

        <div class="input-field col s4 ${status.error ? 'has-error' : ''}">
            <form:input type="text" path="student.name" class="validate"
                        placeholder="Имя" id="stNameInput"></form:input>
            <form:errors path="student.name"></form:errors>
            <label for="stNameInput">Имя</label>
        </div>

        <div class="input-field col s4 ${status.error ? 'has-error' : ''}">
            <form:input type="text" path="student.middleName" class="validate"
                        placeholder="Отчество" id="stMiddleNameInput"></form:input>
            <form:errors path="student.middleName"></form:errors>
            <label for="stMiddleNameInput">Отчество</label>
        </div>
    </div>

    <div class="input-field">
        <i class="material-icons prefix">list</i>
        <select name = "university" id="university">
            <option value="" selected>Choose your option</option>
            <c:forEach var="univer" items="${universities}">
                <option value="${univer.id}">${univer.name}</option>
            </c:forEach>
        </select>
        <label for="university">Выберите университет</label>
    </div>

    <div class="input-field">
        <i class="material-icons prefix">list</i>
        <select id="faculty">
            <option value="" selected>Choose your option</option>
        </select>
        <label for="faculty">Выберите факультет</label>
    </div>

        <div class="input-field">
            <i class="material-icons prefix">list</i>
            <form:select path="student.speciality.id" id="speciality">
                <option value="" selected>Choose your option</option>
            </form:select>
            <label for="speciality">Выберите специальность</label>
        </div>

    <button class="btn waves-effect waves-light right" type="submit" name="action">Принять
        <i class="material-icons right">send</i>
    </button>
</form:form>

获取和发布请求的控制器:

@RequestMapping(value = "/registration", method = RequestMethod.GET)
public ModelAndView registration(@ModelAttribute("registrationForm") RegistrationTO registrationForm,
                                 ModelMap modelMap) {
    ModelAndView modelAndView = new ModelAndView("registrationTemplate");
    if (registrationForm == null) {
        registrationForm = new RegistrationTO();
    }
    modelAndView.addObject("registrationForm", registrationForm);
    modelAndView.addObject("universities", universityService.getAllUniversities());
    //modelAndView.addObject(BindingResult.MODEL_KEY_PREFIX + "registrationForm", modelMap.get("error"));
    return modelAndView;
}
 @RequestMapping(value = "/registration", method = RequestMethod.POST)
public String registration(@ModelAttribute("registrationForm") RegistrationTO registrationForm,
                           BindingResult bindingResult,
                           RedirectAttributes attributes) {

    User userForm = registrationForm.getUser();
    Student studentForm = registrationForm.getStudent();

    userValidator.validate(userForm, bindingResult);

    /*if (bindingResult.hasErrors()) {
        attributes.addFlashAttribute("error", bindingResult);
        attributes.addFlashAttribute("userForm", userForm);
        return "redirect:/registration";
    }*/

    userService.createUser(userForm);

    securityService.autologin(userForm.getEmail(), userForm.getPasswordConfirm());

    return "redirect:/index";
}

在填充字段之后,我单击submit按钮,得到下一条消息:“HTTP状态500-请求处理失败;嵌套异常为org.springframework.beans.NotReadablePropertyException:bean类[by.bsuir.ceres.bean.TO.RegistrationTO]的无效属性‘email’。”:Bean属性“email”不可读或具有无效的getter方法:getter的返回类型是否与setter的参数类型匹配?"

spring似乎不在嵌套bean中搜索属性,但为什么呢?

共有1个答案

蒲坚
2023-03-14

Spring确实支持嵌套属性绑定。在jsp中,有些地方缺少spring bind标记。试试这样。

<form:form method="POST" modelAttribute="registrationForm" commandName="registrationForm" class="col s12">
<input type="hidden" name="${_csrf.parameterName}"
       value="${_csrf.token}" />

<spring:bind path="user.email">
<div class="row">
    <div class="input-field col s12 ${status.error ? 'has-error' : ''}">
        <i class="material-icons prefix">email</i>
        <form:input type="email" path="user.email" class="validate"
                    placeholder="Email" id="loginInput" autofocus="true" />
        <form:errors path="user.email"></form:errors>
        <label for="loginInput">Email</label>
    </div>
</div>
</spring:bind>

<div class="row">
    <spring:bind path="user.password">
    <div class="input-field col s6 ${status.error ? 'has-error' : ''}">
        <i class="material-icons prefix">vpn_key</i>
        <form:input type="password" path="user.password" class="form-control"
                    placeholder="Пароль" id="passwordInput"></form:input>
        <form:errors path="user.password"></form:errors>
        <label for="passwordInput">Пароль</label>
    </div>
    </spring:bind>

    <spring:bind path="user.passwordConfirm">
    <div class="input-field col s6 ${status.error ? 'has-error' : ''}">
        <form:input type="password" path="user.passwordConfirm" class="form-control"
                    placeholder="Повторите пароль" id="secondPasswordInput"></form:input>
        <form:errors path="user.passwordConfirm"></form:errors>
        <label for="secondPasswordInput">Повторите пароль</label>
    </div>
    </spring:bind>
</div>

<div class="row">
    <spring:bind path="student.surname">
    <div class="input-field col s4 ${status.error ? 'has-error' : ''}">
        <i class="material-icons prefix">account_circle</i>
        <form:input type="text" path="student.surname" class="validate"
                    placeholder="Фамилия" id="stSurnameInput"></form:input>
        <form:errors path="student.surname"></form:errors>
        <label for="stSurnameInput">Фамилия</label>
    </div>
    </spring:bind>

    <spring:bind path="student.name">
    <div class="input-field col s4 ${status.error ? 'has-error' : ''}">
        <form:input type="text" path="student.name" class="validate"
                    placeholder="Имя" id="stNameInput"></form:input>
        <form:errors path="student.name"></form:errors>
        <label for="stNameInput">Имя</label>
    </div>
    </spring:bind>

    <spring:bind path="student.middlename">
    <div class="input-field col s4 ${status.error ? 'has-error' : ''}">
        <form:input type="text" path="student.middleName" class="validate"
                    placeholder="Отчество" id="stMiddleNameInput"></form:input>
        <form:errors path="student.middleName"></form:errors>
        <label for="stMiddleNameInput">Отчество</label>
    </div>
    </spring:bind>
</div>

<div class="input-field">
    <i class="material-icons prefix">list</i>
    <select name = "university" id="university">
        <option value="" selected>Choose your option</option>
        <c:forEach var="univer" items="${universities}">
            <option value="${univer.id}">${univer.name}</option>
        </c:forEach>
    </select>
    <label for="university">Выберите университет</label>
</div>

<div class="input-field">
    <i class="material-icons prefix">list</i>
    <select id="faculty">
        <option value="" selected>Choose your option</option>
    </select>
    <label for="faculty">Выберите факультет</label>
</div>

<div class="input-field">
    <i class="material-icons prefix">list</i>
    <form:select path="student.speciality.id" id="speciality">
        <option value="" selected>Choose your option</option>
    </form:select>
    <label for="speciality">Выберите специальность</label>
</div>

<button class="btn waves-effect waves-light right" type="submit" name="action">Принять
    <i class="material-icons right">send</i>
</button>
 类似资料:
  • 本文向大家介绍springMVC返回复杂的json格式数据方法,包括了springMVC返回复杂的json格式数据方法的使用技巧和注意事项,需要的朋友参考一下 一、springMVC返回json格式数据常用的写法是使用@ResponseBody注解,在每一个方法前加上这个注解,springMVC的json解析机制会自动把返回值(Object类型的对象)转换为json格式的数据,如果返回的json对

  • 主要内容:时间复杂度,空间复杂度《 算法是什么》一节提到,解决一个问题的算法可能有多种,这种情况下,我们就必须对这些算法进行取舍,从中挑选出一个“最好”的。 算法本身是不分“好坏”的,所谓“最好”的算法,指的是最适合当前场景的算法。挑选算法时,主要考虑以下两方面因素: 执行效率:根据算法所编写的程序,执行时间越短,执行效率就越高; 占用的内存空间:不同算法编写出的程序,运行时占用的内存空间也不相同。如果实际场景中仅能使用少量的内

  • 本文向大家介绍SpringMVC实现数据绑定及表单标签,包括了SpringMVC实现数据绑定及表单标签的使用技巧和注意事项,需要的朋友参考一下 首先理解数据绑定 为什么要使用数据绑定 基于HTTP特性,所有的用户输入的请求参数类型都是String,比如下面表单: 但我们提交后,为了将请求信息映射到模型中,还需要手动进行格式转换,此外还借助了一个中转对象productForm,其字段名称和Produ

  • 下面是我的控制器和Init活页夹 这样,我想要的日期格式就不起作用了,这是我得到的输出expenseDate=Wed Mar 18 05:30:00 IST 2015,但我希望它变成一种特定的格式,比如yyyy-MM-dd。。。建议我怎么做。

  • 我使用的是Spring Cloud Stream Kafka,但我有一个特殊的服务,它有一个复杂的启动依赖(长时间运行),可能非常脆弱,所以我希望延迟Kafka(消费者)绑定,直到确认成功初始化。 我怎样才能做到这一点?

  • 我正在尝试使用KnockOut在视图上绑定一个复杂对象。js。没有使用overservable()和observableArray(),我就能够将对象绑定到视图。但是,当我实现observable()时,返回的结果将可观察对象添加到我的javascript viewmodel中,并且我的视图无法绑定viewmodel。 下面是服务器端的代码实现: 上述泛型结果的结果将显示在下面的json中 我很抱