Spring MVC - difference between HttpSession.setAttribute and model.addObject

I am trying to learn Spring MVC recently. It seems that I did not understand the functions of the @ModelAttribute and HttpSession annotations very well.

@SessionAttributes({"shoppingCart", "count"}) public class ItemController { @ModelAttribute("shoppingCart") public List<Item> createShoppingCart() { return new ArrayList<Item>(); } @ModelAttribute("count") public Integer createCount() { return 0; } @RequestMapping(value="/addToCart/{itemId}", method=RequestMethod.GET) public ModelAndView addToCart(@PathVariable("itemId") Item item, @ModelAttribute("shoppingCart") List<Item> shoppingCart, @ModelAttribute("count") Integer count) { if(item != null) { shoppingCart.add(item); count = count + 1; } return new ModelAndView(new RedirectView("showAllItems")).addObject("count", count); } @RequestMapping(value="/deleteFromCart/{itemId}", method=RequestMethod.GET) public ModelAndView deleteFromCart(@PathVariable("itemId") Item item, HttpSession session) { List<Item> list = (List<Item>) session.getAttribute("shoppingCart"); list.remove(item); //session.setAttribute("shoppingCart", list); Integer count = (Integer) session.getAttribute("count"); count = count - 1; session.setAttribute("count", count); return new ModelAndView(new RedirectView("showAllItems")); } 

ShoppingCart and count are session attributes.

The problem is the deleteFromCart method. I get count from the session, reassign and overwrite in the session. But I can not see the updated value for counting on jsp. However, the updated shoppingCart object can be seen updated, although I am not overwriting the session object (since the object is the same object that is already in the session).

But why the count is not updated, although I overwrite it with session.setAttribute? When I add a new count object to the model (model.addObject ("count", count)), I can see the updated count value. But why does the session.setAttribute parameter not give the same result?

+6
source share
3 answers

First of all, @SessionAttribute should not use an http session. It uses a SessionAttributeStore , which can have anything as its backup storage. Only the default implementation uses an http session.

The reason your code is not working properly is because @SessionAttribute works.

Before calling the controller method, everything listed in @SessionAttributes , in your case {"warenkorb", "count"} , is read from the session and added to the model.

After the method returns , the session is updated with everything that was added to the model inside the method.

 .addObject("count", count) 
A counter is added to the model.

-> and then the session.

 session.setAttribute("count", count) 

-> count is added to the session, but not to the model. It will be added to the model until the next call to any controller method. But at the moment, the model still has an old count . And the model is added to the request. And if the attribute can be found in the request area, then jsp does not care about what is in the session.

When you use @SessionAttributes and @ModelAttribute (or Spring MVC in general), do not use HttpSession or HttpRequest . Even HttpResponse has limited use. Hug the beauty of Spring MVC instead :)

+10
source

model.addObject places the object in the request area, and HTTPsession.setAttribute places it in the session area. And since the variables in jsp are resolved in the following order: page visibility → request area → scope → application area, you get what you get.

+2
source

Java method parameters are passed values. You can assign to this parameter everything you need inside the method, but it will have no effect outside it. Insisde of the method you are dealing with a copy of the parameter

0
source

Source: https://habr.com/ru/post/944307/


All Articles