如何将Model对象传递到Thymeleaf并通过隐藏字段完整回传给Controller
问题原因
- 你对
th:field属性的用法不符合Thymeleaf规范:th:field只能用于绑定通过th:object声明的表单对象下的单个属性,不能直接传入完整自定义对象,也不能直接使用${}变量取值的写法,因此才会渲染出空的id、name、value属性。 - 隐藏字段的value仅支持存储字符串格式内容,直接传入Java对象无法自动序列化,后端接收时也无法直接反序列化为原对象。
解决方案
根据你的使用场景可以选择以下两种方案:
方案1:表单提交场景(需要前端传递对象)
- 先将7个对象封装为统一的表单传输DTO,添加无参构造、所有属性的getter/setter:
public class FormTransferDTO { private Member member; private Item item; private Poi poi; private MyModel myModel; private List<Plan> allPlans; private List<Poi> allPois; private ItemParam itemParam; // 补全无参构造、所有属性的getter和setter }
- Controller1中将封装好的DTO存入Model:
FormTransferDTO dto = new FormTransferDTO(); dto.setMember(member); dto.setItem(item); dto.setPoi(poi); dto.setMyModel(myModel); dto.setAllPlans(allPlans); dto.setAllPois(allPois); dto.setItemParam(itemParam); model.addAttribute("transferDTO", dto);
- Thymeleaf页面表单绑定DTO,按属性拆分写隐藏字段:
<form th:action="@{/你的后续接口路径}" th:object="${transferDTO}" method="post"> <!-- 单个普通对象按属性逐一绑定 --> <input type="hidden" th:field="*{member.id}"> <input type="hidden" th:field="*{member.name}"> <!-- 把member、item、poi、myModel、itemParam所有需要传递的属性按上述格式依次声明 --> <!-- 集合类型遍历绑定 --> <th:block th:each="plan, stat : *{allPlans}"> <input type="hidden" th:field="*{allPlans[__${stat.index}__].id}"> <input type="hidden" th:field="*{allPlans[__${stat.index}__].content}"> <!-- 把Plan类所有需要传递的属性按上述格式声明 --> </th:block> <th:block th:each="poi, stat : *{allPois}"> <input type="hidden" th:field="*{allPois[__${stat.index}__].id}"> <input type="hidden" th:field="*{allPois[__${stat.index}__].address}"> <!-- 把Poi类所有需要传递的属性按上述格式声明 --> </th:block> <button type="submit">提交</button> </form>
- 后续Controller直接用DTO接收参数:
@PostMapping("/你的后续接口路径") public String handleSubmit(@ModelAttribute FormTransferDTO transferDTO) { // 直接从transferDTO中取出所有需要的对象即可 }
方案2:无需前端感知数据场景(更简单安全)
如果不需要把这些数据暴露给前端,可以直接存在Session中,后续Controller直接从Session取值即可,不需要写前端隐藏字段:
- Controller1中存入Session:
@GetMapping("/controller1的路径") public String controller1Method(HttpSession session) { // 原有业务逻辑 session.setAttribute("member", member); session.setAttribute("item", item); session.setAttribute("poi", poi); session.setAttribute("myModel", myModel); session.setAttribute("allPlans", allPlans); session.setAttribute("allPois", allPois); session.setAttribute("itemParam",itemParam); // 跳转页面 }
- 后续Controller从Session取值:
@RequestMapping("/后续接口路径") public String nextController(HttpSession session) { Member member = (Member) session.getAttribute("member"); Item item = (Item) session.getAttribute("item"); // 依次取出所有需要的对象即可,用完如果不需要可以调用session.removeAttribute("xxx")清理 }
内容的提问来源于stack exchange,提问作者emarwa.mouma.35t
相关产品推荐
相关产品推荐

