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

Spring MVC中第三个控制器@ModelAttribute无法获取Ticket对象

问题分析与解决方案

你的问题核心是表单字段绑定路径不匹配,导致Spring MVC无法将第二个页面提交的嵌套属性值封装回顶层的Ticket对象,最终第三个控制器拿到的是新创建的空对象。以下是具体解决步骤:

1. 修正表单字段的命名前缀

第二个页面的表单绑定的是${ticketObj.participantDTO},但如果表单字段没有带上顶层对象ticketObj的前缀,Spring MVC无法识别这些值属于Ticket对象的嵌套属性。

比如你原来的表单字段可能是:

<input type="text" name="name" value="${ticketObj.participantDTO.name}" />

要改成:

<input type="text" name="ticketObj.participantDTO.name" value="${ticketObj.participantDTO.name}" />

更推荐使用Spring的form标签自动生成正确的字段名,避免手动拼写错误:

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>

<form:form modelAttribute="ticketObj" action="/your-third-controller-url" method="post">
    <form:input path="participantDTO.name" />
    <form:input path="participantDTO.email" />
    <!-- 其他嵌套属性字段 -->
    <button type="submit">提交</button>
</form:form>

form标签会自动生成name="ticketObj.participantDTO.name"这类带前缀的字段,确保Spring能正确映射到Ticket对象的嵌套属性。

2. 确保第三个控制器正确接收对象

第三个控制器的方法需要明确通过@ModelAttribute("ticketObj")接收,同时如果是会话传递的对象,要确保从会话中复用已有对象而非创建新对象:

方式一:复用会话中的Ticket对象

在第三个控制器中添加@ModelAttribute方法,从HttpSession中获取已有的ticketObj,Spring会自动将表单提交的值绑定到这个对象上:

@Controller
public class ThirdController {

    @ModelAttribute("ticketObj")
    public Ticket retrieveTicketFromSession(HttpSession session) {
        // 从会话中获取前两个控制器传递的Ticket对象
        Ticket ticket = (Ticket) session.getAttribute("ticketObj");
        // 防止会话中无对象时创建空对象
        if (ticket == null) {
            ticket = new Ticket();
            session.setAttribute("ticketObj", ticket);
        }
        return ticket;
    }

    @PostMapping("/step3")
    public String handleStep3(@ModelAttribute("ticketObj") Ticket ticketObj) {
        // 此时ticketObj的participantDTO属性已被正确赋值
        System.out.println(ticketObj.getParticipantDTO().getName());
        return "result";
    }
}

方式二:直接绑定(无会话依赖)

如果不需要会话持久化,确保表单字段名与Ticket对象的嵌套路径完全匹配,控制器方法直接接收:

@PostMapping("/step3")
public String handleStep3(@ModelAttribute("ticketObj") Ticket ticketObj) {
    // 处理逻辑
    return "result";
}

3. 验证前两个控制器的对象传递

确认第二个控制器跳转至第三个页面时,已将ticketObj放入模型或会话中:

@Controller
public class SecondController {

    @PostMapping("/step2")
    public String handleStep2(@ModelAttribute("ticketObj") Ticket ticketObj, 
                              HttpSession session, Model model) {
        // 可选:将对象存入会话,跨请求持久化
        session.setAttribute("ticketObj", ticketObj);
        // 或者放入模型,供第二个页面渲染使用
        model.addAttribute("ticketObj", ticketObj);
        return "step3-page";
    }
}

内容的提问来源于stack exchange,提问作者Emrullah Ozkilinc

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 14:45:37