I'm unclear on some subtleties of using @SessionAttributes in Spring MVC via Spring Boot 2.3.3.RELEASE.
- I have two controllers,
Step1ControllerandStep2Controller. - Both controllers use
@SessionAttributes("foobar")at the class level. Step1Controllerduring its request handling for@PostMappingadds a specialFooBarinstance to the model usingmodel.addAttribute("foobar", new FooBar("foo", "bar")).Step2Controller, invoked under a completely independent HTTPPOST, picks up theFooBarinstance in its@PostMappingservice method usingdoSomething(FooBar fooBar).- This all words great!
But I'm unclear on some details of why it works.
The @SessionAttributes API documentation says in part:
Those attributes will be removed once the handler indicates completion of its conversational session. Therefore, use this facility for such conversational attributes which are supposed to be stored in the session temporarily during the course of a specific handler's conversation. For permanent session attributes, e.g. a user authentication object, use the traditional
session.setAttributemethod instead.
- If
@SessionAttributesonly stores model attributes in the HTTP session temporarily and removes them at the end of the conversation, why doesfoobarstill show up in the request toStep2Controller? It appears to me to still be in the session. I don't understand what the docs mean when they refer to "temporarily" and "handler's conversation". It would appearfoobaris stored in the session normally. - It would appear that simply by having
@SessionAttributes("foobar")onStep1Controller, Spring will automatically copyfoobarfrom the model to the session after handling the request. That was sort of hinted at in the documentation, but it only became clear to me through experimentation. - It would appear that by placing
@SessionAttributes("foobar")onStep2Controller, Spring copiesfoobarfrom the session to the model before the request. This was not clear to me at all from the documentation. - And finally, note that in
Step2Controller.doSomething(FooBar fooBar)I don't have any annotation at all on theFooBarparameter, other than the@SessionAttributes("foobar")(but that is on the controller class). The documentation seemed to indicate I need to add a@ModelAttributeannotation to the method parameter, such asStep2Controller.doSomething(@ModelAttribute("foobar") FooBar fooBar)or at leastStep2Controller.doSomething(@ModelAttribute FooBar fooBar). But Spring still seems to find the session variable, even with no annotation at all on the parameter. Why? How would I have known this?
This is on of the things that has always bugged me about Spring: too many things happen "magically", with no clear documentation of what is expected to happen. People who use Spring for years I suppose just get a "feel" for what works and doesn't; but a new developer looking at the code just has to trust that it magically does what it's supposed to.
Could someone clarify why what I have described works, especially enlightening me on the first question? Maybe that way I too can develop this "Spring sense" to instinctively know which incantations to evoke. Thank you.