Spring MVC: 选项不会保持选中状态


问题内容

我有一个添加新老师的简单表格。我<form:select>在视图中使用Spring
来显示教师职称列表,但是当我选择一个选项而不输入教师的姓氏和/或姓氏时,由于我正在对所有三个字段进行验证,因此在提交后加载页面时,先前选择的选项丢失,并且“选择标题”文本再次出现。

这是控制器:

@RequestMapping(value="/add", method = RequestMethod.POST)
public String postAddTeacher(@RequestParam(value = "title") Integer titleId, 
        @Validated(Teacher.TeacherChecks.class) @ModelAttribute("teacherAttribute") Teacher teacher,
        BindingResult result,
        Model model) {

    logger.debug("Received request to add new teacher");

    if (result.hasErrors()) {
        if (titleId != null) {
            model.addAttribute("titleList", titleService.getAll());
            Title title = titleService.get(titleId);
            teacher.setTitle(title);
            model.addAttribute("teacher", teacher);
            return "addTeacher";
        }
        else {
            model.addAttribute("titleList", titleService.getAll());
            return "addTeacher";
        }
    }
    else {
        teacherService.add(titleId, teacher);
        return "success/addTeacherSuccess";
    }
}

这是视图:

<c:url var="saveUrl" value="/essays/main/teacher/add" />
<form:form modelAttribute="teacherAttribute" method="POST" action="${saveUrl}">
<form:errors path="*" cssClass="errorblock" element="div" />

<form:label path="title"></form:label>
<form:select path="title" id="titleSelect">
    <form:option value="" label="Select title" />
    <form:options items="${titleList}" itemValue="titleId" itemLabel="titleDescription" />              
</form:select>
<form:errors path="title" cssClass="error"/>

<form:label path="firstName">First name:</form:label>
<form:input path="firstName"/>
<form:errors path="firstName" cssClass="error"/>

<form:label path="lastName">Last name:</form:label>
<form:input path="lastName"/>
<form:errors path="lastName" cssClass="error"/>

 <input type="submit" value="Submit" />
</form:form>

以防万一这是老师豆:

@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "TEACHER_ID", unique = true, nullable = false)
private Integer teacherId;

@NotNull(message = "Teacher's first name is null!", groups = TeacherChecks.class)
@NotBlank(message = "Please enter teacher's first name!", groups = TeacherChecks.class)
@Column(name = "FIRST_NAME", nullable = false, length = 50)
private String firstName;

@NotNull(message = "Teacher's last name is null!", groups = TeacherChecks.class)
@NotBlank(message = "Please enter teacher's last name!", groups = TeacherChecks.class)
@Column(name = "LAST_NAME", nullable = false, length = 50)
private String lastName;

@NotNull(message = "Please choose title!", groups = TeacherChecks.class)
@Valid
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch=FetchType.EAGER)
@JoinColumn(name = "TITLE_FK", nullable = false)
private Title title;

@ManyToMany(mappedBy = "teachers")
private Set<Activity> activities;

public Teacher() {
}
// getters & setters

页面重新加载后,我想保留选择的选项。尽管它会自动发生,例如当我在文本字段中输入值时,即使在页面重新加载后,它也会停留在该位置。有人可以帮我吗?有没有一种方法可以从控制器执行此操作,或者必须在视图中完成?如何执行?

更新

我按照@willOEM的建议添加value="${teacherAttribute.title}"<form:select>,但仍然无法正常工作。现在看起来像这样:

<form:select path="title" id="titleSelect" value="${teacherAttribute.title}">
    <form:option value="" label="Select title" />
    <form:options items="${titleList}" itemValue="titleId" itemLabel="titleDescription" />              
</form:select>

问题答案:

您的模型包括一个title引用Title类的属性。这是不一样的title,你指的是在您的形式,这实际上是一个titleId。由于titleId并非的一部分modelAttribute,因此应将其从<form:xxx>标记中排除。您将需要使用一个普通<select>标签来将所选内容传递titleId回控制器进行处理。不幸的是,使用<select>标签时,您不能仅使用JSTL设置value属性,因此必须seelcted基于该titleId值(如果已设置)有条件地设置该选项的属性。如果titleListTitle对象的简单列表,则可以通过<select>以下方式创建标签:

<select id="titleInput" name="titleId">
    <option value=""></option>
    <c:forEach items="${titleList}" var="title">
        <c:when test="${title.titleId== titleId}">
            <option value="${title.titleId}" selected>${title.titleName}</option>
        </c:when>
        <c:otherwise>
            <option value="${title.titleId}" >${title.titleName}</option>
        </c:otherwise>
    </c:forEach>
</select>

在您的控制器中,@RequestParam注释将拉出titleId提交的数据。由于它不是的一部分,因此modelAttribute您需要确保将其添加为模型属性:

...
if (result.hasErrors()) {
    if (titleId != null) {
        model.addAttribute("titleId", titleId);  // <--This line added
        model.addAttribute("titleList", titleService.getAll());
        Title title = titleService.get(titleId);
        teacher.setTitle(title);
        model.addAttribute("teacher", teacher);
        return "addTeacher";
    }
    else {
        model.addAttribute("titleList", titleService.getAll());
        return "addTeacher";
    }
}
...

希望我们这次能做到。