You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Model对象传递到Thymeleaf并通过隐藏字段完整回传给Controller

问题原因

  • 你对th:field属性的用法不符合Thymeleaf规范:th:field只能用于绑定通过th:object声明的表单对象下的单个属性,不能直接传入完整自定义对象,也不能直接使用${}变量取值的写法,因此才会渲染出空的id、name、value属性。
  • 隐藏字段的value仅支持存储字符串格式内容,直接传入Java对象无法自动序列化,后端接收时也无法直接反序列化为原对象。

解决方案

根据你的使用场景可以选择以下两种方案:

方案1:表单提交场景(需要前端传递对象)

  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
}
  1. 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);
  1. 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>
  1. 后续Controller直接用DTO接收参数:
@PostMapping("/你的后续接口路径")
public String handleSubmit(@ModelAttribute FormTransferDTO transferDTO) {
    // 直接从transferDTO中取出所有需要的对象即可
}

方案2:无需前端感知数据场景(更简单安全)

如果不需要把这些数据暴露给前端,可以直接存在Session中,后续Controller直接从Session取值即可,不需要写前端隐藏字段:

  1. 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);
    // 跳转页面
}
  1. 后续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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 14:15:06