When do @SessionAttributes in SpringMVC get remove

2019-03-18 07:00发布

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?

2条回答
神经病院院长
2楼-- · 2019-03-18 07:28

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.

查看更多
在下西门庆
3楼-- · 2019-03-18 07:46

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");
}
查看更多
登录 后发表回答