会话中的弹簧存储对象

Posted

技术标签:

【中文标题】会话中的弹簧存储对象【英文标题】:Spring store object in session 【发布时间】:2012-04-19 13:41:12 【问题描述】:

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

【问题讨论】:

【参考方案1】:
@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);

【讨论】:

是的,“替代选项”有效,但我不想使用它。当我在控制器中创建私有属性购物车时,我收到错误消息“找不到依赖项的匹配 bean:预期至少 1 个 bean 有资格作为此依赖项的自动装配候选者。依赖项注释:@org.springframework.beans.factory.annotation.Autowired(required=true)"。 bean 应该在 applicationContext.xml 中定义为 ? 没有。在调度程序-servlet.xml 中。或者,正如我所展示的 - 用注释声明 嗯,但是当我使用注释时,在 dispatcher-servlet.xml 中没有 bean 定义时,我得到了我之前粘贴的错误,另外,当我使用注释并定义 bean 时,我只使用该控制器得到 404 . 注解应该与结合。但是xml也可以 @Bozho - 如果我们的购物车中有多个商品,这会起作用吗?这是我的问题link【参考方案2】:

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

以下是解决方案的简要总结:

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

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

【讨论】:

正确的网址是richardchesterwood.blogspot.co.uk/2011/03/… 注意,对于解决方案#4,不要在任何方法上使用 final。这样做,访问器将是单例的,而不是会话范围,因为 AOP 无法拦截决赛。【参考方案3】:

您只需要使用会话和代理模式添加 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

【讨论】:

【参考方案4】:

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

【讨论】:

以上是关于会话中的弹簧存储对象的主要内容,如果未能解决你的问题,请参考以下文章

HP Fortify:ASP.NET 不良做法:存储在会话中的不可序列化对象

弹簧反应的弹簧安全会话超时

在 Rails 的会话中存储对象

使用 window 对象进行会话存储而不是 AmplifyJS 存储

不能自动配置会话存储库(会话存储类型为“redis”)

内置对象Session,Cookie