I am writing a wizard-like controller that handles the management of a single bean across multiple views. I use @SessionAttributes to store the bean, and SessionStatus.setComplete() to terminate the session in the final call. However, if the user abandons the wizard and goes to another part of the application, I need to force Spring to re-create the @ModelAttribute when they return. For example:
@Controller
@SessionAttributes("commandBean")
@RequestMapping(value = "/order")
public class OrderController
{
@RequestMapping("/*", method=RequestMethod.GET)
public String getCustomerForm(@ModelAttribute("commandBean") Order commandBean)
{
return "customerForm";
}
@RequestMapping("/*", method=RequestMethod.GET)
public String saveCustomer(@ModelAttribute("commandBean") Order commandBean, BindingResult result)
{
[ Save the customer data ];
return "redirect:payment";
}
@RequestMapping("/payment", method=RequestMethod.GET)
public String getPaymentForm(@ModelAttribute("commandBean") Order commandBean)
{
return "paymentForm";
}
@RequestMapping("/payment", method=RequestMethod.GET)
public String savePayment(@ModelAttribute("commandBean") Order commandBean, BindingResult result)
{
[ Save the payment data ];
return "redirect:confirmation";
}
@RequestMapping("/confirmation", method=RequestMethod.GET)
public String getConfirmationForm(@ModelAttribute("commandBean") Order commandBean)
{
return "confirmationForm";
}
@RequestMapping("/confirmation", method=RequestMethod.GET)
public String saveOrder(@ModelAttribute("commandBean") Order commandBean, BindingResult result, SessionStatus status)
{
[ Save the payment data ];
status.setComplete();
return "redirect:/order";
}
@ModelAttribute("commandBean")
public Order getOrder()
{
return new Order();
}
}
If a user makes a request to the application that would trigger the “getCustomerForm” method (i.e., http://mysite.com/order), and there’s already a “commandBean” session attribute, then “getOrder” is not called. I need to make sure that a new Order object is created in this circumstance. Do I just have to repopulate it manually in getCustomerForm?
Thoughts? Please let me know if I’m not making myself clear.
Yes, sounds like you may have to repopulate it manually in
getCustomerForm– if an attribute is part of the@SessionAttributesand present in the session, then like you said@ModelAttributemethod is not called on it.An alternative may be to define a new controller with only
getCustomerFormmethod along with the@ModelAttribute methodbut without the @SessionAttributes on the type so that you can guarantee that @ModelAttribute method is called, and then continue with the existing @RequestMapped methods in the existing controller.