Home > Back-end >  Store and retrieve an object in session through @Scope("session")
Store and retrieve an object in session through @Scope("session")

Time:12-15

I am having a Spring shopping project and I am working on a cart with I can add new product to it and store it in the session. I create a Cart class to store it in the session

import java.util.HashMap;

import org.springframework.stereotype.Component;

import org.springframework.context.annotation.Scope;

@Component
@Scope("session")
public class Cart {
    
    // key: product id
    // value: product information
    private HashMap<Integer,Product> productlist;

    public HashMap<Integer, Product> getProductlist() {
        return productlist;
    }

    public void setProductlist(HashMap<Integer, Product> productlist) {
        this.productlist = productlist;
    }
    
}

I create a Controller class to get the cart from session and add product to it

@Controller
@Scope("request")
public class AddToCartController {

    @Autowired
    private Cart cart;
    
    @Autowired
    ProductService proService;
    
    @RequestMapping("/cart/add")
    public String addToCart(@RequestParam Optional<String> pid) {
        
        if(pid.isPresent()) {
            
            Product productinfo = proService.getProductByPid(pid.get());
            
            if(productinfo.getQuantity()>0) { 
                
                int pidInteger = Integer.parseInt(pid.get());
                
                
                try {
                    Product product = cart.getProductlist().get(pidInteger);
                    
                    // there is already product in cart. add 1 to quantity

                    cart.getProductlist().get(pidInteger).setQuantity(product.getQuantity() 1);
                    
                } catch(NullPointerException e) {

                    // add the new product to cart with quantity 1

                    productinfo.setQuantity(1);
                    cart.getProductlist().put(pidInteger, productinfo);
                    
                }
                
            }
            
        } 
        
        return "redirect:/cart";
    }
}

But when I call this controller it send back an error

java.lang.NullPointerException: null
    at com.example.phonestore.controller.AddToCartController.addToCart(AddToCartController.java:45) ~[classes/:na]

CodePudding user response:

Could you try with using a Proxy,

       @Scope(value = WebApplicationContext.SCOPE_SESSION,
        proxyMode = ScopedProxyMode.TARGET_CLASS)

Example:

@Component
@Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class VisitorInfo implements Serializable {
  private String name;
  private int visitCounter;
  private LocalDateTime firstVisitTime;
  //getters/setters
    .............
}

You could also use the annotation @SessionScope which is the same as the above configuration:

Specifically, {@code @SessionScope} is a composed annotation that acts as a shortcut for {@code> @Scope("session")} with the default {@link #proxyMode} set to {@link ScopedProxyMode#TARGET_CLASS TARGET_CLASS}.

https://github.com/Hunoob/Spring-Framework/blob/a7aa3dd2927e4e2ae470a639bc4b1fccd6315273/spring-web/src/main/java/org/springframework/web/context/annotation/SessionScope.java

CodePudding user response:

I think the NullPointerException is caused by you didn't initialize the "productlist". You can try something like this: "private HashMap<Integer,Product> productlist = new HashMap<>();".

It's ok to use the "session scope" on the cart without specifying the "proxyMode" attribute of the "@Scope" annotation, if the "request scope" controller is the only bean has an dependency on it.

But usually the Controller should be "singleton" scope, unless you have a good reason for choosing another kind of scope. And if the Controller is "singleton" scope, you should specify the "proxyMode" attribute of the "@Scope" annotation.

  • Related