2012-04-05 10 views
24

Me gustaría implementar un carrito de compras con Spring, así que tengo que guardar un objeto Cart (que tiene atributos como products, paymentType y deliveryType) en sesión. He intentado crearlo con bean y atribuir "scope" a "sesión", pero simplemente no funciona, ¿debo usar algunas anotaciones adicionales en mi controlador o clase Cart? Cualquier uso de ejemplo sería realmente útil :-) Gracias de antemano.Spring store objeto en la sesión

Respuesta

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

y luego

@Inject 
private Cart cart; 

debería funcionar, si se declara en el contexto web (despachador-servlet.xml). Una opción alternativa es utilizar la sesión prima y puesto que el objeto de la compra No:

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

Sí, funciona una opción alternativa, pero no quiero usarla. Cuando creo un carro de atributos privado en mi controlador, recibo el error "No se encontró ningún bean coincidente para la dependencia: se esperaba al menos 1 bean que califica como candidato de autowire para esta dependencia. Anotaciones de dependencia: {@ org.springframework.beans.factory.annotation.Autowired (required = true)} ". El bean debe definirse en applicationContext.xml como ? – tomaszf

+1

no. En dispatcher-servlet.xml. O, como mostré, declarado con las anotaciones – Bozho

+0

Hmm, pero cuando uso anotaciones, sin la definición de bean en dispatcher-servlet.xml, obtengo el error que pegué antes, más cuando uso anotaciones y defino bean solo obtengo 404 solo con ese controlador. – tomaszf

13

Si se inyecta el carrito de la compra directamente en el controlador, el problema está probablemente sucede porque el controlador es Singleton con ámbito (por defecto) , que es un alcance más amplio que el bean que está inyectando. Este excelente artículo ofrece una descripción general de cuatro enfoques para exactamente lo que está tratando de hacer: http://richardchesterwood.blogspot.co.uk/2011/03/using-sessions-in-spring-mvc-including.html.

He aquí un breve resumen de las soluciones:

  1. Ámbito del controlador de ámbito de sesión (@scope("session") uso en el nivel de controlador) y sólo tiene una instancia de carrito de la compra en el controlador.
  2. Alcance el controlador para solicitarlo e inyectar el carrito de compras del ámbito de la sesión.
  3. Simplemente use la sesión directamente - algo desordenado, IMO.
  4. Utilice la anotación de Spring <aop:scoped-proxy/>.

Todos los métodos tienen sus pros y sus contras. Yo suelo ir con la opción 2 o 4. La opción 4 es en realidad bastante simple y es el único enfoque que he visto documented by Spring.

+0

La URL correcta es http: // richardchesterwood. blogspot.co.uk/2011/03/using-sessions-in-spring-mvc-including.html – Gilead

+0

Gracias @Gilead. Actualicé con la URL correcta. –

+0

Nota, con la solución n. ° 4, no use el método final en ningún método. Haga eso y ese acceso será singleton, no sesión con alcance ya que AOP no puede interceptar finales. –

2

Sólo tiene que añadir una anotación Alcance de la siguiente manera con el modo de sesión y el proxy

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

Dónde cada vez que necesita para el carro de compras objeto, puede Autowire que

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


    @Autowired 
    ShoppingCart shoppingCart; 
} 

Revelación: he desarrollado un proyecto de ejemplo, que utiliza Spring MVC, AngularJS y de arranque que demuestran el alcance sesión de primavera -
https://github.com/dpaani/springmvc-shoppingcart-sample

Cuestiones relacionadas