如何使用SpringMVC和Thymeleaf将表值绑定到映射和post?
我有一个条目表单,用户在其中选择填充表格的项目子集。我需要将每行的第一列和第三列值分别绑定到键和值,将它们输入到通过控制器传入的映射中,然后发布数据。我在网上浏览了很多不同的解决方案,但还没有找到一个有效的。地图总是返回空的 映射的包装类如何使用SpringMVC和Thymeleaf将表值绑定到映射和post?,spring,spring-mvc,thymeleaf,Spring,Spring Mvc,Thymeleaf,我有一个条目表单,用户在其中选择填充表格的项目子集。我需要将每行的第一列和第三列值分别绑定到键和值,将它们输入到通过控制器传入的映射中,然后发布数据。我在网上浏览了很多不同的解决方案,但还没有找到一个有效的。地图总是返回空的 映射的包装类 @Getter @Setter public class ItemForm { private Map<Integer, Integer> items = new HashMap<>(); } 模板 <tr th:eac
@Getter @Setter
public class ItemForm {
private Map<Integer, Integer> items = new HashMap<>();
}
模板
<tr th:each="item : *{items}">
<td>
<input type="text" th:value="${item.key}">
</td>
<td></td>
<td>
<input type="text" th:field="*{items[__${item.key}__]}">
</td>
</tr>
编辑:
我真的不想在这个问题上花费更多的时间,而且似乎没有一个优雅的解决方案,所以我只想使用Ajax POST请求。您将映射的单个键/值绑定到表单,而不是映射本身。那样不行。我很确定没有办法从表格中取回整张地图。也许用转换器 另一种方法是为输入字段分配名称/id,并在processItemUpdate方法中将所有键/值读回映射: 此解决方案适用于我的站点。我更准确地重新定义了我的答案: input.html
<!DOCTYPE HTML>
<html lang="de" xmlns:th="http://www.thymeleaf.org">
<head />
<body>
<form th:action="@{/inputPost}" method="post" th:fragment="form">
<table>
<tr th:each="item,iter : ${itemForm.items.entrySet()}">
<td><input type="text" th:id="${iter.index + '.ID'}"
th:name="${iter.index + '.ID'}" th:value="${item.key}"></td>
<td><input type="text" th:id="${iter.index + '.VALUE'}"
th:name="${iter.index + '.VALUE'}" th:value="${item.value}"></td>
</tr>
</table>
<input type="submit" name="Send" value="Send" /> <input type="submit"
name="Add" value="Add new Line" />
</form>
</body>
</html>
success.html
<!DOCTYPE HTML>
<html lang="de" xmlns:th="http://www.thymeleaf.org">
<head></head>
<body>
<table border="1">
<tr th:each="item : ${itemForm.items.entrySet()}">
<td th:text="${item.key}"></td>
<td th:text="${item.value}"></td>
</tr>
</table>
</body>
</html>
控制器
@GetMapping("/inputForm")
public String dummy(Model model) {
ItemForm form = new ItemForm();
form.getItems().put(form.getItems().size(), 42);
model.addAttribute("itemForm", form);
return "input";
}
@PostMapping("/inputPost")
public String processItemUpdate(HttpServletRequest request, Model model) {
Map<String, String[]> params = request.getParameterMap();
ItemForm form = new ItemForm();
String operation = null;
for (Entry<String, String[]> entry : params.entrySet()) {
if (entry.getKey().endsWith(".ID")) { // only react on ID values. The values will be directly fetched from
// map
String[] tokens = StringUtils.split(entry.getKey(), ".");
Integer id = Integer.parseInt(tokens[0]);
Integer idValue = Integer.parseInt(entry.getValue()[0]);
String[] value = params.get(id + ".VALUE"); // fetch the value to defined ID
Integer valueValue = Integer.parseInt(value[0]);
form.getItems().put(idValue, valueValue);
} else if (entry.getKey().equalsIgnoreCase("Send")) { // determine operation
operation = "send";
} else if (entry.getKey().equalsIgnoreCase("Add")) { // determine operation
operation = "add";
}
}
model.addAttribute("itemForm", form);
if (operation.equals("add")) { // add a new line and resend form again
form.getItems().put(form.getItems().size(), 42);
return "input";
}
return "success";
}
@GetMapping(“/inputForm”)
公共字符串虚拟(模型){
ItemForm form=新的ItemForm();
form.getItems().put(form.getItems().size(),42);
model.addAttribute(“itemForm”,form);
返回“输入”;
}
@后映射(“/inputPost”)
公共字符串processItemUpdate(HttpServletRequest请求,模型){
Map params=request.getParameterMap();
ItemForm form=新的ItemForm();
字符串操作=null;
for(条目:params.entrySet()){
if(entry.getKey().endsWith(“.ID”){//仅对ID值作出反应。这些值将直接从
//地图
String[]tokens=StringUtils.split(entry.getKey(),”);
整数id=Integer.parseInt(标记[0]);
Integer idValue=Integer.parseInt(entry.getValue()[0]);
String[]value=params.get(id+“.value”);//将值提取到定义的id
整数值=Integer.parseInt(值[0]);
form.getItems().put(idValue,valueValue);
}else if(entry.getKey().equalsIgnoreCase(“发送”){//确定操作
操作=“发送”;
}else if(entry.getKey().equalsIgnoreCase(“Add”){//确定操作
操作=“添加”;
}
}
model.addAttribute(“itemForm”,form);
if(operation.equals(“add”){//添加新行并重新发送表单
form.getItems().put(form.getItems().size(),42);
返回“输入”;
}
返回“成功”;
}
不幸的是,这不起作用。即使在修改模板之后,参数映射似乎也不包含任何值。@bliss这个经过改进的示例应该可以工作并满足您的要求。
<!DOCTYPE HTML>
<html lang="de" xmlns:th="http://www.thymeleaf.org">
<head></head>
<body>
<table border="1">
<tr th:each="item : ${itemForm.items.entrySet()}">
<td th:text="${item.key}"></td>
<td th:text="${item.value}"></td>
</tr>
</table>
</body>
</html>
@GetMapping("/inputForm")
public String dummy(Model model) {
ItemForm form = new ItemForm();
form.getItems().put(form.getItems().size(), 42);
model.addAttribute("itemForm", form);
return "input";
}
@PostMapping("/inputPost")
public String processItemUpdate(HttpServletRequest request, Model model) {
Map<String, String[]> params = request.getParameterMap();
ItemForm form = new ItemForm();
String operation = null;
for (Entry<String, String[]> entry : params.entrySet()) {
if (entry.getKey().endsWith(".ID")) { // only react on ID values. The values will be directly fetched from
// map
String[] tokens = StringUtils.split(entry.getKey(), ".");
Integer id = Integer.parseInt(tokens[0]);
Integer idValue = Integer.parseInt(entry.getValue()[0]);
String[] value = params.get(id + ".VALUE"); // fetch the value to defined ID
Integer valueValue = Integer.parseInt(value[0]);
form.getItems().put(idValue, valueValue);
} else if (entry.getKey().equalsIgnoreCase("Send")) { // determine operation
operation = "send";
} else if (entry.getKey().equalsIgnoreCase("Add")) { // determine operation
operation = "add";
}
}
model.addAttribute("itemForm", form);
if (operation.equals("add")) { // add a new line and resend form again
form.getItems().put(form.getItems().size(), 42);
return "input";
}
return "success";
}