我最近正在尝试学习Spring MVC。似乎我不太了解@ModelAttribute注释和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和count是会话属性。
问题出在deleteFromCart方法中。我从会话中获得计数,重新分配并在会话中覆盖。但我无法看到jsp的更新值。但是,可以看到更新的shoppingCart对象已更新,但我不会覆盖会话对象(因为该对象是已在会话中的同一对象)。
但是为什么计数没有更新,尽管我用session.setAttribute覆盖它? 当我将新的计数对象添加到模型(model.addObject(“count”,count))时,我可以看到更新的count值。但是为什么session.setAttribute没有给出相同的结果呢?
答案 0 :(得分:10)
首先,@SessionAttribute
不必使用http会话。它使用SessionAttributeStore
,可以将任何内容作为其后备存储。只有默认实现使用http会话。
您的代码无法正常工作的原因在于@SessionAttribute
的工作原理。
在调用控制器方法之前,@SessionAttributes
中列出的所有内容(在您的案例中为{"warenkorb", "count"}
)都会从会话中读取并添加到模型中。
方法返回后会话将更新为方法中已添加到模型的所有内容。
.addObject("count", count)
- &GT; count被添加到模型中,然后添加到会话中。
session.setAttribute("count", count)
- &GT; count被添加到会话中但不添加到模型中。它将在下一次调用任何控制器方法之前添加到模型中。但就目前而言,该模型仍然具有旧的count
。并且模型是添加到请求中的内容。如果可以在请求范围中找到属性,那么jsp并不关心会话中的内容。
当您使用@SessionAttributes
和@ModelAttribute
(或一般的Spring MVC)时,请避免使用HttpSession
或HttpRequest
。即使HttpResponse
的用途也很有限。拥抱Spring MVC
的美丽而不是:)
答案 1 :(得分:2)
model.addObject
将对象放入请求范围,而HTTPsession.setAttribute
将其放入会话范围。并且由于jsp上的变量在下一个订单上得到解决:页面范围 - &gt;请求范围 - &gt;会话范围 - &gt;应用范围,你得到你得到的。
答案 2 :(得分:0)
Java方法参数由值传递。你可以为这个paramateter分配你想要的方法,但它不会在它之外产生任何影响。你正在处理param副本
的方法