Reputation: 13240
Under what exact circumstances do @SessionAttributes get cleared? I've discovered some confusing behaviour when trying to use two models in a page.
When I do a GET followed by a POST using this controller...
@Controller
@RequestMapping("/myPage*")
@SessionAttributes(value = {"object1", "object2"})
public class MyController {
@RequestMapping(method = RequestMethod.GET)
public String get(Model model) {
model.addAttribute("object1", new Object1());
model.addAttribute("object2", new Object2());
return "myPage";
}
@RequestMapping(method = RequestMethod.POST)
public String post(@ModelAttribute(value = "object1") Object1 object1) {
//do something with object1
return "myPage";
}
}
...object2 gets cleared from the Model. It no longer exists as a @SessionAttribute and cannot be accessed on my view page.
However if the signature of the second method is modified to this...
public String post(@ModelAttribute(value = "object1") Object1 object1,
@ModelAttribute(value = "object2") Object2 object2) {
...then object2 does not get cleared from the model and is available on my view page.
The javadoc for @SessionAttributes says:
... attributes will be removed once the handler indicates completion of its conversational session.
But I don't see how I have indicated completion of the conversational session in the first example but not in the second example.
Can anyone explain this behaviour or is it a bug?
Upvotes: 13
Views: 25379
Reputation: 490
You can remove single session level ModelAttribute like this:
Given ModelMap model
, HttpSession session
and you do:
if (categoryId != null)
model.addAttribute("categoryId", categoryId);
else {
model.remove("categoryId");
session.removeAttribute("categoryId");
}
Upvotes: 1
Reputation: 11818
You indicate completion of the conversation by calling
SessionStatus.setComplete
public void post(...., SessionStatus status) {
status.setComplete();
}
That said, I don't see why you should be loosing one model attribute and not the other.
Have you tried doing something like:
@ModelAttribute("object1")
public Object object1() { return new Object(); }
@ModelAttribute("object2")
public Object object2() { return new Object(); }
And see how that compares to putting the attributes in the model by hand.
Upvotes: 14