Spring MVC - différence entre HttpSession.setAttribute et le modèle.addObject
Je suis en train d'apprendre Spring MVC récemment. Il semble que je ne comprenais pas bien les fonctionnalités de @ModelAttribute d'annotation et de HttpSession.
@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 et comptent sont les attributs de session.
Le problème est dans la deleteFromCart méthode. Je reçois le compter de session, réaffecter et remplacer en session. Mais je ne peux pas le voir la mise à jour de la valeur de compter sur jsp. Toutefois, la mise à jour shoppingCart objet peut être vu à jour, bien que je ne remplace pas l'objet de session (puisque l'objet est le même objet qui est déjà en cours).
Mais pourquoi est le nombre de pas mis à jour, bien que je la remplacer par de la session.setAttribute?
Quand j'ai ajouter le nouveau compte de l'objet du modèle (le modèle.addObject("count", count)) alors je peux voir la mise à jour de la valeur de comptage. Mais pourquoi ne pas en session.setAttribute donner le même résultat?
Vous devez vous connecter pour publier un commentaire.
Tout d'abord,
@SessionAttribute
n'a pas à utiliser de la session http. Il utilise unSessionAttributeStore
qui peut avoir n'importe quoi comme à son support de stockage. Seule l'implémentation par défaut utilise la session http.La raison pour laquelle votre code ne fonctionne pas comme prévu réside dans la façon dont
@SessionAttribute
œuvres.Avant un contrôleur méthode est appelée, tout ce qui est inscrit dans
@SessionAttributes
, dans votre cas{"warenkorb", "count"}
, est lu à partir de la session et ajoutés au modèle.Après la méthode a repris la session est mis à jour avec tout ce qui a été ajouté au modèle dans la méthode.
-> count est ajouté au modèle et par la suite à la session.
-> count est ajouté à la session, mais pas le modèle. Il sera ajouté au modèle avant la prochaine invocation de la méthode du contrôleur. Mais comme pour l'instant, le modèle a encore le vieux
count
. Et le modèle est ce qui est ajouté à la demande. Et si un attribut peut être trouvé dans la demande portée puis la jsp ne se soucie pas de ce qui est dans la session.Lorsque vous utilisez
@SessionAttributes
et@ModelAttribute
(ou Spring MVC en général), alors évitez d'utiliserHttpSession
ouHttpRequest
. MêmeHttpResponse
est d'une utilité limitée. D'embrasser la beauté deSpring MVC
à la place 🙂model.addObject
met de l'objet de la demande portée alors queHTTPsession.setAttribute
le met à la portée de session. Et depuis variables sur les jsp sont réglés dans l'ordre suivant: page champ d'application -> champ d'application request -> session -> la portée de l'application, vous obtenez ce que vous obtenez.public ModelAndView deleteFromBasket(@PathVariable Integer position, @ModelAttribute("warenkorb") List<Item> warenkorb, @ModelAttribute("count") Integer count, ModelMap modelMap)
et de définir l'attribut de session n':modelMap.addAttribute("count", --count);
Méthode Java params sont passés par valeurs. Vous pouvez attribuer à ce paramateter rien yoou voulez à l'intérieur de la méthode, mais il n'aura pas de ny effet en dehors d'elle . Insisde de la méthode que vous avez à traiter avec la copie de l'param