2012-04-05 3 views
24

Я хотел бы реализовать корзину с Spring, поэтому мне нужно сохранить объект Cart (который имеет атрибуты, такие как продукты, тип оплаты и тип доставки) в сеансе. Я попытался создать его с bean и атрибутом «scope», установленным в «session», но он просто не работает, следует ли использовать некоторые дополнительные аннотации в моем контроллере или класс Cart? Любое использование примера было бы очень полезно :-) Спасибо заранее.Spring store object in session

ответ

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

, а затем

@Inject 
private Cart cart; 

должен работать, если он объявлен в веб-контексте (диспетчеру-servlet.xml). Альтернативный вариант заключается в использовании необработанного сессии и поставить объект корзины есть:

@RequestMapping(..) 
public String someControllerMethod(HttpSession session) { 
    session.addAttribute(Constants.CART, new Cart(); 
    ... 
    Cart cart = (Cart) session.getAttribute(Constants.CART); 
} 
+0

Да, «альтернативный вариант» работает, но я не хочу его использовать. Когда я создаю частную корзину атрибутов в своем контроллере, я получаю сообщение об ошибке «Нет подходящего компонента для зависимостей: ожидается не менее 1 bean, который квалифицируется как кандидат autwire для этой зависимости. Аннотации зависимостей: {@ org.springframework.beans.factory.annotation.Autowired (required = true)} ". Боб должен быть определен в applicationContext.xml как tomaszf

+1

№ в dispatcher-servlet.xml. Или, как я показал - объявлен с аннотациями – Bozho

+0

Хм, но когда я использую аннотации, без определения bean-компонента в dispatcher-servlet.xml, я получаю ошибку, которую я вставляю раньше, плюс когда я использую аннотации, и я определяю bean-компонент, я просто получаю только 404 только с этим контроллером. – tomaszf

13

Если вы инъекционные магазинную тележку непосредственно в контроллер, проблема, скорее всего, происходит потому, что ваш контроллер одноточечно область действия (по умолчанию) , который имеет более широкий масштаб, чем компонент, который вы вводите. В этой замечательной статье приведен обзор четырех подходов к тому, что вы пытаетесь сделать: http://richardchesterwood.blogspot.co.uk/2011/03/using-sessions-in-spring-mvc-including.html.

Вот краткий обзор решений:

  1. Scope контроллер размах сеанса (использование @scope("session") на уровне контроллера) и просто есть корзина экземпляр в контроллере.
  2. Освойте контроллер, чтобы запросить и введите в корзину для покупок в зоне сеанса.
  3. Просто используйте сеанс напрямую - вроде грязный, ИМО.
  4. Использовать аннотацию Spring <aop:scoped-proxy/>.

Все методы имеют свои плюсы и минусы. Я обычно хожу с опцией 2 или 4. Вариант 4 на самом деле довольно простой и единственный подход, который я видел documented by Spring.

+0

Правильный URL-адрес: http: // richardchesterwood. blogspot.co.uk/2011/03/using-sessions-in-spring-mvc-including.html – Gilead

+0

Спасибо @Gilead. Я обновил правильный URL. –

+0

Обратите внимание, что с решением № 4 не использовать final для любого метода. Сделайте это, и этот аксессуар будет одинарным, а не сеансом, поскольку AOP не может перехватить финалы. –

2

Вам просто нужно добавить Scope аннотацию, как показано ниже с сеанса и режиме прокси

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

Где когда вам нужно использовать объект корзины покупок, вы можете autowire его

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


    @Autowired 
    ShoppingCart shoppingCart; 
} 

Раскрытие информации: Я разработал типовой проект, который использует Spring MVC, angularJS и самозагрузки, демонстрирующих объем весенней сессии -
https://github.com/dpaani/springmvc-shoppingcart-sample