6

我最近正在尝试学习 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上看不到 count 的更新值。但是,可以看到更新后的 shoppingCart 对象已更新,尽管我没有覆盖会话对象(因为该对象与已经在会话中的对象相同)。

但是为什么计数没有更新,虽然我用 session.setAttribute 覆盖它?当我将新的计数对象添加到模型(model.addObject(“count”,count))时,我可以看到更新的计数值。但是为什么 session.setAttribute 没有给出相同的结果呢?

4

3 回答 3

13

首先,@SessionAttribute不一定要使用http会话。它使用SessionAttributeStore可以有任何东西作为其后备存储的 a。只有默认实现使用 http 会话。

您的代码无法按预期工作的原因在于其@SessionAttribute工作方式。

在调用控制器方法之前@SessionAttributes,在您的情况下,从会话中读取列出的所有内容{"warenkorb", "count"}并将其添加到模型中。

在方法返回后,会话将使用方法中添加到模型的所有内容进行更新。

.addObject("count", count)

-> count 添加到模型中,然后添加到会话中。

session.setAttribute("count", count)

-> 计数被添加到会话而不是模型。它将在下一次调用任何控制器方法之前添加到模型中。但就目前而言,该模型仍然具有旧的count. 模型是添加到请求中的内容。如果可以在请求范围内找到属性,则 jsp 不关心会话中的内容。

当您使用@SessionAttributesand @ModelAttribute(或一般的 Spring MVC)时,请避免使用HttpSessionor HttpRequest。即使HttpResponse是有限的使用。拥抱美丽,Spring MVC而不是:)

于 2013-05-05T20:35:56.530 回答
2

model.addObject将对象放入请求范围,同时HTTPsession.setAttribute将其放入会话范围。由于 jsp 上的变量在下一个顺序上被解析:页面范围 -> 请求范围 -> 会话范围 -> 应用程序范围,所以你得到了你得到的。

于 2013-05-05T13:58:14.990 回答
0

Java 方法参数是按值传递的。您可以在方法内为这个参数分配任何您想要的东西,但在它之外不会有任何效果。您正在处理参数副本的方法的 Insisde

于 2014-09-14T04:18:06.033 回答