我正在开发一个Spring MVC 3.1应用程序(使用控制器注释),我遇到了一个问题,我不确定如何解决。我有一个页面,根据数据,为用户构建一个表单以进行POST。表单可以包含可变数量的字段和任意数量的文件。我还没有找到一个如何编写控制器方法来处理这个问题的例子。
我见过的大多数示例都使用静态表单,因此开发人员可以编写一个对象来绑定表单数据。然而,在我的情况下,由于表格长度不同,我不会真的有这个选择(我认为)。
使用Spring可以实现这一点吗?
答案 0 :(得分:1)
以下是旧项目的示例。
表格。注意form:form标签上的modelAttribute属性。这就是告诉Spring将支持对象绑定到表单,反之亦然。为了简洁,我删除了很多字段。只剩下地区(多值)和价格。
<form:form method="post" modelAttribute="bindableCourse" id="courseForm">
<%-- regions --%>
<div class="default-block">
<form:label path="regions">
Regions
</form:label>
<c:forEach items="${allRegions}" var="region">
<span class="inlineCheckBox"><form:checkbox path="regions" value="${region.id}" label="${region.name}"/></span>
</c:forEach>
<div><br><a href="#" id="selectAllRegions"><spring:message code="course.form.regions.selectall.linktext"/></a><br><br></div>
<form:errors path="regions" cssClass="form-error"/>
</div>
<%-- price (formatted) --%>
<div class="default-block">
Price</form:label>
<form:input path="formattedPrice" cssErrorClass="form-input-error" size="10"/>
<spring:message code="course.form.currencysymbol"/> <spring:message code="course.form.price.perperson"/>
<form:errors path="formattedPrice" cssClass="form-error"/>
</div>
</form:form>
Controller具有此表单的GET和POST方法。在GET方法中,我们将bindableCourse添加到模型中。注意名称&#34; bindableCourse&#34;对应于JSP表单中的modelAttribute属性。在POST方法中,我们捕获用户为此BindableCourse提交的内容。
@Controller
public class CourseController {
// This is called when accessing the form for the first time
@RequestMapping(value = "/admin/course/add", method = RequestMethod.GET)
public String newCourse(Model model, Locale locale) {
BindableCourse bindableCourse = new BindableCourse();
model.addAttribute("bindableCourse", bindableCourse);
model.addAttribute("mainContent", "forms/editCourse");
addDataToModel(model, locale, companyService.getCurrentlyLoggedInCompany());
return "adminMain";
}
// This is called when submitting the form.
// Note that Spring created a BindableCourse for us,
// filled with the user entered values. This is Spring binding in action.
// Happens behind the scenes.
@RequestMapping(value = "/admin/course/add", method = RequestMethod.POST)
public String addCourse(@ModelAttribute("bindableCourse") BindableCourse bindableCourse, BindingResult result,
RedirectAttributes redirectAttributes, Model model, Locale locale) {
validator.validate(bindableCourse, result);
if (!result.hasErrors()) {
Course course = courseService.save(bindableCourse);
bindableCourse.setPublishable(true);
redirectAttributes.addFlashAttribute("valid", "true");
return "redirect:/admin/course/" + course.getId();
}
addDataToModel(model, locale, companyService.getCurrentlyLoggedInCompany());
model.addAttribute("valid", "false");
model.addAttribute("mainContent", "forms/editCourse");
return "adminMain";
}
}
最后是表单对象&#34; BindableCourse&#34;。这只是一个简单的Java对象,可以在表单之间传输数据。
public class BindableCourse {
private Long id;
private String name;
private String shortDescription;
private String longDescription;
private String certificateText;
private String duration;
// A multivalued property. The user can select multiple regions with multiple checkboxes
// But you can also use multiple fields with the same name like address[0], address[1], etc
private List<Long> regions = new ArrayList<Long>();
private long category;
private List<String> tags = new ArrayList<String>();
private String formattedPrice;
private boolean certificate;
private String certificateName;
private List<Long> times = new ArrayList<Long>();
private List<String> dates = new ArrayList<String>();
private List<Long> options = new ArrayList<Long>();
private Calendar firstPublished;
private boolean published;
private boolean publishable;
private String linkToSite;
// getters and setters ommitted
}
在我使用的JSP表单中,您可以看到后端提供了多值区域。我正在迭代一个&#34; allRegions&#34;采集。这些在控制器中添加到addDataToModel()方法中的模型中(此处未显示)。在您的场景中,您将使用Javascript在前端向表单添加新字段,但想法是一样的。
答案 1 :(得分:0)
使用包装器封装表单数据。
例如:
public class WrapperForm {
private List<String> Fields;
public List<String> getFields() {
return Fields;
}
public void setFields(List<String> fields) {
Fields = fields;
}
}
然后你可以在其中放入x字段(通过控制器方法):
@RequestMapping(method = RequestMethod.POST)
protected String processFinish(ModelMap model) {
//process request -> need x fields in form
WrapperForm formFields = new WrapperForm();
formFields.setFields(new ArrayList<String>());
for (int i = 0; i<x;i++){
formFields.getFields().add("anyDefaultValue");
}
model.addAttribute("formFields", formFields);
return "youJsp";
}
最后一步:你的jsp。
您只需要将核心JSTL库放入表单应答器中,例如:
<c:forEach items="${formFields.fields}" varStatus="i">
<form:input path="fields[${i.index}]"/>
</c:forEach>