I have form object that I set to request in GET request handler in my Spring controller. First time user enters to page, a new form object should be made and set to request.
The job of @SessionAttribute
is to bind an existing model object to the session. If it doesn't yet exist, you need to define it. It's unnecessarily confusing, in my opinion, but try something like this:
@SessionAttributes({"form"})
@Controller
public class MyController {
@RequestMapping(value="form", method=RequestMethod.GET)
public ModelAndView viewForm(@ModelAttribute("form") Form form) {
ModelAndView mav = new ModelAndView("form");
if(form == null) form = new Form();
mav.addObject("form", form);
return mav;
}
@RequestMapping(value="form", method=RequestMethod.POST)
@Transactional(readOnly = true)
public ModelAndView saveForm(@ModelAttribute("form") Form form) {
// ..etc etc
}
}
Note that the @SessionAttributes
is declared on the class, rather than the method. You can put wherever you like, really, but I think it makes more sense on the class.
The documentation on this could be much clearer, in my opinion.
I'm struggling with this as well. I read this post and it made some things clearer:
Set session variable spring mvc 3
As far as I understood it this basically says:
So if you want to have objects that last longer throughout multiple GET and POST requests you will have to add them manually to the HttpSession, as usual.
@Controller
@SessionAttributes("goal")
public class GoalController {
@RequestMapping(value = "/addGoal", method = RequestMethod.GET)
public String addGoal(Model model) {
model.addAttribute("goal", new Goal(11));
return "addGoal";
}
@RequestMapping(value = "/addGoal", method = RequestMethod.POST)
public String addGoalMinutes(@ModelAttribute("goal") Goal goal) {
System.out.println("goal minutes " + goal.getMinutes());
return "addMinutes";
}
}
On page addGoal.jsp user enters any amount and submits page. Posted amount is stored in HTTP Session because of
@ModelAttribute("goal") Goal goal
and
@SessionAttributes("goal")
Without @ModelAttribute("goal") amount entered by user on addGoal page would be lost
It throws Exception if controller called first time even though added @SessionAttributes({"form"}) to class. So add following populateForm method will fix this.
@SessionAttributes({"form"})
@Controller
public class MyController {
@ModelAttribute("form")
public Form populateForm() {
return new Form(); // populates form for the first time if its null
}
@RequestMapping(value="form", method=RequestMethod.GET)
public ModelAndView viewForm(@ModelAttribute("form") Form form) {
ModelAndView mav = new ModelAndView("form");
if(form == null) form = new Form();
mav.addObject("form", form);
return mav;
}
@RequestMapping(value="form", method=RequestMethod.POST)
@Transactional(readOnly = true)
public ModelAndView saveForm(@ModelAttribute("form") Form form) {
// ..etc etc
}
}
if there is no defined session object so I think it's gonna be like this:
@SessionAttributes({"form"})
@Controller
public class MyController {
@RequestMapping(value="form", method=RequestMethod.GET)
public ModelAndView viewForm() {
ModelAndView mav = new ModelAndView("form");
if(form == null) form = new Form();
mav.addObject("form", form);
return mav;
}
@RequestMapping(value="form", method=RequestMethod.POST)
@Transactional(readOnly = true)
public ModelAndView saveForm(@ModelAttribute("form") Form form) {
// ..etc etc
}
}