如何通过Thymeleaf提交HTML表单,将数据绑定为Spring Controller接收的Map类型
实现方案
步骤1:定义后端基础类
首先完成自定义枚举和单行DTO的定义,满足Spring参数绑定的基础要求:
// 自定义的行Key枚举示例 public enum Key { key1, key2, key3, // 共32个枚举值对应表格32行 // 剩余枚举值省略 }
// 单行数据对应的DTO,必须包含无参构造、对应属性的getter和setter public class SimplerDTO { private int val1; private int val2; private int val3; private int val4; // 无参构造 public SimplerDTO() {} // getter、setter请自行补充,不可省略 }
步骤2:修改Thymeleaf页面输入框命名
按照Spring MVC的参数绑定规则,Map类型参数的表单字段命名格式为参数名[键值].子属性,直接调整输入框的name属性即可:
<th:block th:each="key: ${keys}"> <input th:name="|table[${key}].val1|" /> <input th:name="|table[${key}].val2|" /> <input th:name="|table[${key}].val3|" /> <input th:name="|table[${key}].val4|" /> </th:block>
注意此处的table前缀要和后续Controller里的参数名完全一致,${key}输出的内容必须和你自定义的Key枚举名称完全匹配(大小写一致)。
步骤3:调整Controller参数绑定
提供两种可选绑定方式,第二种兼容性更高更推荐:
方式1:直接绑定Map参数
给Map参数添加@RequestParam注解即可完成自动绑定:
@PostMapping("/the/path") public void saveTable(Model model, @RequestParam Map<Key, SimplerDTO> table){ // 业务逻辑省略 }
方式2:外层包裹DTO(更稳定,避免绑定失效)
如果直接绑定Map出现类型转换异常,可以定义外层DTO包裹Map,再用@ModelAttribute绑定,兼容性更好:
首先定义外层DTO:
public class TableFormDTO { private Map<Key, SimplerDTO> table; // getter、setter、无参构造请自行补充 }
Controller调整为:
@PostMapping("/the/path") public void saveTable(Model model, @ModelAttribute TableFormDTO form){ Map<Key, SimplerDTO> table = form.getTable(); // 业务逻辑省略 }
注意事项
- 所有DTO必须提供无参构造方法、对应属性的getter和setter,否则Spring无法完成参数注入
- 如果输入框允许为空,建议把SimplerDTO的属性类型改成包装类
Integer,避免空值转换基础类型报错 - 前端传入的key值必须和Key枚举的名称完全匹配,否则会出现枚举转换异常
内容的提问来源于stack exchange,提问作者Edgar Ramos - d3249
相关产品推荐
相关产品推荐

