@SessionAttributes allows you to save current sessions of model attributes between requests and is intended for a specific user. The goal was to create a design that would be a step towards realizing the conversation area (shorter than the session, longer than the request). This blog explains the need for interactive reach and why itβs not fully accessible with @SessionAttributes .
It allows you to automatically save the appropriate attributes of the model (matching is based on the name). The default is HttpSession, but it can also be configured in different ways. Docs say
The session attributes specified in this annotation correspond to the specific attributes of the processor model that are transparently stored in the conversation session. These attributes will be deleted after the handler indicates the end of the conversation.
This bit, however, those attributes will be deleted as soon as the handler indicates the end of the session. does not happen automatically, and the developer must specify the exit from the session using setComplete in the SessionStatus instance. Otherwise, the attribute of the models will remain in the session, often an undesirable side effect.
The easiest way to understand the difference is to observe the scope and value of the model variable, the model variable supported by @SessionAttribute, and the βnormalβ HttpSession variable.
Take a look at two simple controllers
@Controller @SessionAttributes("modelAndSession") @RequestMapping("/sessionattr") public class FirstController { protected static final String NEXT_VIEW = "next"; @RequestMapping("/init") public String handlingMethod1( Model model, HttpSession session) { model.addAttribute(NEXT_VIEW, "/sessionattr/afterinit"); session.setAttribute("session", "TRUE"); model.addAttribute("modelAndSession", "TRUE"); model.addAttribute("model", "TRUE"); return "index"; } @RequestMapping("/afterinit") public String handlingMethod2(SessionStatus status, Model model) { model.addAttribute(NEXT_VIEW, "/nosessionattr/init");
second controller
@Controller @RequestMapping("/nosessionattr") public class SecondController { protected static final String NEXT_VIEW = "next"; @RequestMapping("/init") public String handlingMethod3(Model model) { model.addAttribute(NEXT_VIEW, "/sessionattr/init"); return "index"; } }
and the view that will cause the thread
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <a href="${next}">Next step ${next}</a> <hr/> <table> <thead> <th>key</th> <th>Request scope</th> <th>Session scope</th> </thead> <tr> <td>model</td> <td>${requestScope.model}</td> <td>${sessionScope.model}</td> </tr> <tr> <td>model and session</td> <td>${requestScope.modelAndSession}</td> <td>${sessionScope.modelAndSession}</td> </tr> <tr> <td>session</td> <td>${requestScope.session}</td> <td>${sessionScope.session}</td> </tr> </table>
Flow
At the initial request /sessionattr/init view is as follows

therefore, the model variable is available in the request area, the session attribute is available both in the request and in the session area, as well as in the βnormalβ session attribute, available only in the session area
At the next request /sessionattr/afterinit view is as follows

therefore, the variable only for the model will disappear, and the @SessionAttribute model attribute will be transferred from the session to the model and stored in the requests. The next step will target the second controller /nosessionattr/init , and the view will look like this

now the @SessionAttribute model object is removed from the model, but since status.setComplete is not explicitly called, it remained in the session as a normal variable
This is a particularly confusing scenario, since many expect the @SessionAttribute model object to disappear after the handler switches, however, if it is not explicitly cleared, it remains in the session. Feel free to copy the fragments and further study the combination that bothers you