40

我想用 Spring 实现一个购物车,所以我需要Cart在会话中保存一个对象(具有 products、paymentType 和 deliveryType 等属性)。我尝试使用 bean 和属性“范围”设置为“会话”来创建它,但它不起作用,我应该在我的控制器或Cart类中使用一些额外的注释吗?任何示例用法都会非常有帮助:-) 在此先感谢。

4

4 回答 4

47
@Component
@Scope("session")
public class Cart { .. }

进而

@Inject
private Cart cart;

如果它在 Web 上下文中声明(dispatcher-servlet.xml),它应该可以工作。另一种选择是使用原始会话并将您的购物车对象放在那里:

@RequestMapping(..)
public String someControllerMethod(HttpSession session) {
    session.setAttribute(Constants.CART, new Cart());
    ...
    Cart cart = (Cart) session.getAttribute(Constants.CART);
}
于 2012-04-05T19:56:03.537 回答
13

如果您将购物车直接注入您的控制器,则可能会出现问题,因为您的控制器是单例范围的(默认情况下),它比您注入的 bean 范围更广。这篇出色的文章概述了您正在尝试做的四种方法:http ://richardchesterwood.blogspot.co.uk/2011/03/using-sessions-in-spring-mvc-include.html 。

以下是解决方案的快速摘要:

  1. 将控制器范围限定为会话范围(@scope("session")在控制器级别上使用),并且控制器中只有一个购物车实例。
  2. 将控制器范围限定为请求并注入会话范围的购物车。
  3. 只需直接使用会话 - 有点混乱,IMO。
  4. 使用 Spring 的注解<aop:scoped-proxy/>

所有方法都有其优点和缺点。我通常选择选项 2 或 4。选项 4 实际上非常简单,并且是我见过的 Spring 记录的唯一方法。

于 2012-04-05T20:12:13.100 回答
4

您只需要使用会话和代理模式添加 Scope 注释,如下所示

@Component
@Scope(value="session", proxyMode=ScopedProxyMode.TARGET_CLASS)
public class ShoppingCart implements Serializable{
}

无论您需要在哪里使用购物车对象,都可以自动装配它

@Service
public class ShoppingCartServiceImpl implements ShoppingCartService {
    Logger logger = LoggerFactory.getLogger(ShoppingCartServiceImpl.class);


    @Autowired
    ShoppingCart shoppingCart;
}

披露:我开发了一个示例项目,它使用 spring MVC、angularJS 和 bootstrap 来演示 Spring Session 范围 -
https://github.com/dpaani/springmvc-shoppingcart-sample

于 2013-10-16T18:49:06.967 回答
3

尝试自动连接 HttpSession 和 spring 将注入 HttpSession 的代理 @Autowired private HttpSession httpSession;

于 2020-04-29T00:40:01.190 回答