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}.
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.