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
相关产品推荐
相关产品推荐

