Today I’m going to start writing about shopping carts. Here are four questions:
1) The user does not log in the user name and password, add the product, close the browser and open it again, do not log in the user name and password?
2) The user logs in the user name and password, adds the product, closes the browser and opens it again, does not log in the user name and password?
3) The user login username and password, add goods, close the browser, and then open again, login username and password ask: is the cart goods still in?
4) The user login user name password, add goods, close the browser foreign hometown open the browser login user name and password ask: shopping cart goods still in?
The above four questions are based on JINGdong as the template, so guess what the result is?
1) in
2) It’s gone
3) in
4) in
If you can guess the answer, then you are really good, but how do these four things work out? (If you do not agree with the partners can use JINGdong experiment)
Let’s take a look at the principle of shopping cart, and finally the specific code implementation.
1) The user does not log in and adds the product. At this time, the product is added to the Cookie of the browser, so when the user visits again (without logging in), the product is still in the Cookie, so the product in the shopping cart still exists.
2) After the user logs in and adds the product, both the Cookie and the product selected by the user will be added to the shopping cart, and then the product in the Cookie will be deleted. Therefore, when the user visits again (without logging in), the shopping cart item in the Cookie has been deleted, so the item in the shopping cart is no longer there.
3) The user logs in and adds goods. At this time, the goods are added to the database for persistent storage. Open the login user name and password again, and the goods selected by the user must still exist, so the goods in the cart still exist.
4) the reason 3)
Here are the advantages of saving items to cookies without login and the comparison between saving items to Session and database:
1: Cookie: Advantage: save the user browser (do not waste our company’s server) Disadvantage: Cookie is disabled, do not provide save
2: Session: (Redis: waste a lot of server memory: implement and disable cookies) fast
3: The database (Mysql, Redis, SOlr) can persist the database speed is too slow
So what I want to talk about today is:
-
User not logged in: Shopping cart added to Cookie
-
User login: Save shopping cart to Redis (no database)
Overall idea diagram:
Here is a code example to implement the shopping cart function:
Let’s take a look at the design of the shopping cart and the shopping item:
Shopping cart: buyerCart.java
1 Public class BuyerCart implements Serializable{2 3 /** 3 */ 6 private static Final Long serialVersionUID = 1L; 9 private List<BuyerItem> items = new ArrayList<BuyerItem>(); 12 public void addItem(BuyerItem item){13 if (items. Contains (item)) {15 // Add number 16 for (BuyerItem buyerItem : items) { 17 if (buyerItem.equals(item)) { 18 buyerItem.setAmount(item.getAmount() + buyerItem.getAmount()); 19 } 20 } 21 }else { 22 items.add(item); 23 } 24 25 } 26 27 public List<BuyerItem> getItems() { 28 return items; 29 } 30 31 public void setItems(List<BuyerItem> items) { 32 this.items = items; 38 @jsonIgnore 39 public Integer getProductAmount(){40 Integer result = 0; 42 for (BuyerItem BuyerItem: items) {43 result += buyeritem.getAmount (); 44 } 45 return result; 49 @jsonignore 50 public Float getProductPrice(){51 Float result = 0f; For (BuyerItem BuyerItem: items) {54 result += buyeritem.getAmount ()* buyeritem.getsku ().getprice (); 55 } 56 return result; 61 public Float getFee(){62 Float result = 0f; If (getProductPrice() < 79) {65 result = 5f; 66 } 67 68 return result; @jsonignore 73 public Float getTotalPrice(){74 return getProductPrice() + getFee(); 75} 76 77}Copy the code
The @jsonigonre annotation is used because we need to convert BuyerCart to Json, and these fields only have get methods, so we can’t convert them, so we need to ignore Json.
Here is the shopping item: buyeritem.java
1 public class BuyerItem implements Serializable{ 2 3 private static final long serialVersionUID = 1L; 4 5 //SKu object 6 private SKu SKu; 9 private Boolean isHave = true; Private Integer Amount = 1; 13 14 public Sku getSku() { 15 return sku; 16 } 17 18 public void setSku(Sku sku) { 19 this.sku = sku; 20 } 21 22 public Boolean getIsHave() { 23 return isHave; 24 } 25 26 public void setIsHave(Boolean isHave) { 27 this.isHave = isHave; 28 } 29 30 public Integer getAmount() { 31 return amount; 32 } 33 34 public void setAmount(Integer amount) { 35 this.amount = amount; 36 } 37 38 @Override 39 public int hashCode() { 40 final int prime = 31; 41 int result = 1; 42 result = prime * result + ((sku == null) ? 0 : sku.hashCode()); 43 return result; 49} 45 46 @override 47 public Boolean equals(Object obj) {48 if (this == obj) return true; 50 if (obj == null) 51 return false; 52 if (getClass() ! = obj.getClass()) 53 return false; 54 BuyerItem other = (BuyerItem) obj; 55 if (sku == null) { 56 if (other.sku ! = null) 57 return false; 58 } else if (! sku.getId().equals(other.sku.getId())) 59 return false; 60 return true; 62 61}}Copy the code
1. Add the goods to the shopping cart
2 function addCart(){3 // + skuId 4 windot.location. href="/shopping/buyerCart? skuId="+skuId+"&amount="+$("#buy-num").val(); 5}Copy the code
The parameters passed in here are skuId(the primary key of the inventory table, the item ID, color, size, stock, etc.), purchase amount.
Now let’s look at how controllers are handled:
@requestMapping (value="/shopping/buyerCart") 3 public <T> String buyerCart(Long skuId, Integer amount, HttpServletRequest request, 4 HttpServletResponse response) throws JsonParseException, JsonMappingException, IOException{5 // convert object to JSON string /json string to object 6 ObjectMapper om = new ObjectMapper(); 7 om.setSerializationInclusion(Include.NON_NULL); 8 BuyerCart buyerCart = null; 9 //1, get cart in Cookie 10 Cookie[] cookies = request.getcookies (); 11 if (null ! = cookies && cookies.length > 0) { 12 for (Cookie cookie : Cookies) {13 // 14 if (Constants.buyer_cart.equals (cookie.getName())) {15 // Swap cart object with JSON string 16 buyerCart = om.readValue(cookie.getValue(), BuyerCart.class); 17 break; 23 if (null == buyerCart) {24 buyerCart = new buyerCart (); 25} 26 27 //3, add current item to cart 28 if (null! = skuId && null ! = amount) { 29 Sku sku = new Sku(); 30 sku.setId(skuId); 31 BuyerItem buyerItem = new BuyerItem(); 32 buyerItem.setSku(sku); Buyeritem. setAmount(amount); 36 buyercart. addItem(buyerItem); List<BuyerItem> items = buyercart.getitems (); 41 Collections.sort(items, new Comparator<BuyerItem>() { 42 43 @Override 44 public int compare(BuyerItem o1, BuyerItem o2) { 45 return -1; 46} 47 48}); 49 50 // The first three login and non-login do the same operation, In fourth, you need to determine 51 String username = sessionProviderService. GetAttributterForUsername (RequestUtils. GetCSessionId (request, response)); 52 if (null ! = username) {/ / logged in 54 / / 4, 53 in the shopping cart add to Redis. 55 cartService insertBuyerCartToRedis (buyerCart, username); 57 Cookie Cookie = new Cookie(Constants.BUYER_CART, null); 58 cookie.setPath("/"); 59 cookie.setMaxAge(-0); 60 response.addCookie(cookie); 61}else {62 // not login 63 //4, save shopping cart to Cookie 64 // Convert object to JSON format 65 Writer w = new StringWriter(); 66 om.writeValue(w, buyerCart); 67 Cookie cookie = new Cookie(Constants.BUYER_CART, w.toString()); 69 cookie.setPath("/"); 71 cookie.setMaxAge(24*60*60); 70 // Set the Cookie expiration time: -1 indicates that the browser is invalid after closing. 72 //5,Cookie write browser 73 response.addcookie (Cookie); 76 / / 6, 74} 75 redirect 77 return "redirect: / shopping/toCart"; 78}Copy the code
Converting an object to a JSON string/converting a JSON string to an object
We’ll write a small Demo here to demonstrate the interchange between JSON and objects, using the ObjectMapper class from SpringMVC.
1 public class TestJson { 2 3 @Test 4 public void testAdd() throws Exception { 5 TestTb testTb = new TestTb(); 6 testtb.setName (" Fan Bingbing "); 7 ObjectMapper om = new ObjectMapper(); 8 om.setSerializationInclusion(Include.NON_NULL); 10 Writer wr = new StringWriter(); 11 om.writeValue(wr, testTb); 12 System.out.println(wr.toString()); TestTb r = om.readValue(wr.toString(), testtb.class); 16 System.out.println(r.toString()); 17} 18 19}Copy the code
Execution Result:
Here we use include.non_null. If TestTb is null, we do not convert it to Json. Objectmapper.writevalue () is used from object –>Json string. From Json string –> objectMapper.readValue(). Going back to the code in our project above, the item will only be added to the Cookie if you haven’t logged in to add it.
1 // Not logged in 2 //4, save shopping cart to Cookie 3 // Convert object to JSON format 4 Writer w = new StringWriter(); 5 om.writeValue(w, buyerCart); 6 Cookie cookie = new Cookie(Constants.BUYER_CART, w.toString()); 7 // setPath to share cookies. 8 cookie.setPath("/"); 0: immediately becomes invalid >0: the unit is seconds. 10 Cookie. setMaxAge(24*60*60); 11 //5,Cookie write browser 12 response.addcookie (Cookie);Copy the code
We debug can see:
Here you have converted the object shopping cart object buyerCart to Json format.
To add an item to the cart, whether logged in or not, first fetch the cart in the Cookie and then append the currently selected item to the cart.
Then log in to empty the shopping cart in the Cookie, and add the contents of the shopping cart to Redis for persistent storage.
If you are not logged in, append the selected item to the Cookie.
InsertBuyerCartToRedis code to append the cart to Redis :insertBuyerCartToRedis
Public void insertBuyerCartToRedis(BuyerCart, BuyerCart, String username){ 3 List<BuyerItem> items = buyerCart.getItems(); 4 if (items.size() > 0) {5 // Redis saves Map set whose skuId is key and amount is value. String> hash = new HashMap<String, String>(); 7 for (BuyerItem item : If (jedis. Hexists ("buyerCart:"+username, String.valueOf(item.getSku().getId()))) { 10 jedis.hincrBy("buyerCart:"+username, String.valueOf(item.getSku().getId()), item.getAmount()); 11 }else { 12 hash.put(String.valueOf(item.getSku().getId()), String.valueOf(item.getAmount())); 13 } 14 } 15 if (hash.size() > 0) { 16 jedis.hmset("buyerCart:"+username, hash); 17} 18} 19 20}Copy the code
Check whether the user is logged in: String username = sessionProviderService.getAttributterForUsername(RequestUtils.getCSessionId(request, response));
1 public class RequestUtils {2 2 public static String getsession id (HttpServletRequest Request, HttpServletResponse Response){5 //1, retrieve Cookie from request.getcookies (); CSessionID 8 if (null! = cookies && cookies.length > 0) { 9 for (Cookie cookie : Cookies) {10 if ("CSESSIONID".equals(cookie.getName())) {11 return cookie.getValue(); 13} 14} 15} 16 // No, create a CSessionId, put it in Cookie and return to browser. Return new CSessionID 17 String CSessionID = uuID.randomuuid ().toString().replaceAll("-", ""); Cookie Cookie = new Cookie("CSESSIONID", CSESSIONID); 21 cookie.setPath("/"); >0 Survival time, seconds 23 cookie.setMaxAge(-1); 24 25 return csessionid; 26}} 27Copy the code
1/2 / access to public String getAttributterForUsername (String jessionId) {3 String value = jedis. Get (jessionId + ":USER_NAME"); 4 if(null ! Expire (jedis.expire(jessionId + ":USER_NAME", 60*exp); 7 return value; 8 } 9 return null; 10}Copy the code
2. Shopping cart display page
The last page is redirected to the shopping cart display: return “redirect: / shopping/toCart”; There are two ways to enter the settlement page:
1) Click on the product details page to add to cart.
2) Directly click the shopping cart button to enter the shopping cart settlement page.
Here’s the code for the settlement page:
1 @Autowired 2 private CartService cartService; 3 // Go to the shopping cart to pay, there are two places to direct: 4 @requestMapping (value="/shopping/toCart") 5 public String toCart(Model Model) HttpServletRequest request, 6 HttpServletResponse response) throws JsonParseException, JsonMappingException, IOException{7 // Convert object to JSON string /json string to object 8 ObjectMapper om = new ObjectMapper(); 9 om.setSerializationInclusion(Include.NON_NULL); 10 BuyerCart buyerCart = null; 12 Cookie[] cookies = request.getcookies (); 13 if (null ! = cookies && cookies.length > 0) { 14 for (Cookie cookie : Cookies) {15 // 16 if (Constants.buyer_cart.equals (cookie.getName())) {17 // Swap cart object with JSON string 18 buyerCart = om.readValue(cookie.getValue(), BuyerCart.class); 19 break; 20} 21} 22} 23 24 // Check whether to log in 25 String username = sessionProviderService.getAttributterForUsername(RequestUtils.getCSessionId(request, response)); 26 if (null ! = username) {27 // select * from *; Will be in the shopping cart to save something to Redis 29 if (null = = buyerCart) {30 cartService. InsertBuyerCartToRedis (buyerCart, username); 32 Cookie Cookie = new Cookie(Constants.BUYER_CART, null); 33 cookie.setPath("/"); 34 cookie.setMaxAge(-0); 35 response.addCookie(cookie); 36} 37 / / 3, take out Redis in the shopping cart. 38 buyerCart = cartService selectBuyerCartFromRedis (username); If (null == buyerCart) {buyerCart = new buyerCart (); List<BuyerItem> items = buyercart.getitems (); 49 if(items.size() > 0){50 // Add skU information to the shopping cart only if there is a shopping cart item. items) { 52 buyerItem.setSku(cartService.selectSkuById(buyerItem.getSku().getId())); 57 model. AddAttribute ("buyerCart", buyerCart); 60 return "cart"; 61}Copy the code
Here is the shopping cart details display page. It should be noted that if the same product is added continuously, it needs to be combined.
The display page of shopping cart details includes two blocks: 1) product details 2) Total (total amount of goods, freight)
1) The product details also include the product size, color, purchase quantity and availability.
Remove the Redis in the shopping cart: buyerCart = cartService. SelectBuyerCartFromRedis (username);
Public BuyerCart selectBuyerCart CartFromredis (String username){3 BuyerCart BuyerCart = new BuyerCart(); Redis = skuId (key), amount (value) String> hgetAll = jedis.hgetAll("buyerCart:"+username); 6 Set<Entry<String, String>> entrySet = hgetAll.entrySet(); 7 for (Entry<String, String> entry : entrySet) { 8 //entry.getKey(): skuId 9 Sku sku = new Sku(); 10 sku.setId(Long.parseLong(entry.getKey())); 11 BuyerItem buyerItem = new BuyerItem(); 12 buyerItem.setSku(sku); 13 //entry.getValue(): amount 14 buyerItem.setAmount(Integer.parseInt(entry.getValue())); 16 buyercart. addItem(buyerItem); 17 } 18 19 return buyerCart; 20}Copy the code
List
items = buyercart.getitems (); buyerItem.setSku(cartService.selectSkuById(buyerItem.getSku().getId()));
1 // Add the corresponding data to the shopping item in the shopping cart, query the SKU object by skuId, color object, Commodity object 2 public Sku selectSkuById (Long skuId) {3 Sku Sku = skuDao. SelectByPrimaryKey (skuId); 4 / color / 5 sku. SetColor (colorDao. SelectByPrimaryKey (sku. GetColorId ())); 6 / / add commodity information 7 sku. SetProduct (productDao. SelectByPrimaryKey (sku. GetProductId ())); 8 return sku; 9}Copy the code
It then returns to “cart.jsp”, which is the shopping cart details display page.
3. Go to the settlement page
At this point, the user must be logged in and must have items in the cart.
So here we need to use the Filtering function of SpringMVC, the user must log in first when clicking settlement, if not, the user will be prompted to log in.
1 @requestMapping (value="/buyer/trueBuy") 3 public String trueBuy(String[] skuIds, Model Model, HttpServletRequest Request, HttpServletResponse Response. 6 String username = sessionProviderService.getAttributterForUsername(RequestUtils.getCSessionId(request, response)); 7 / / take out all the shopping cart 8 BuyerCart BuyerCart = cartService. SelectBuyerCartFromRedisBySkuIds (skuIds, username); 9 List<BuyerItem> items = buyerCart.getItems(); 10 If (items.size() > 0) {11 if (items.size() > 0) {11 if (items.size() > 0) {13 Boolean flag = true; 14 //2, the goods in the shopping cart must be in stock and the purchase quantity is greater than the stock quantity is considered as no stock. Tip: The original page of shopping cart does not move. 15 for (BuyerItem BuyerItem: Items) {16 // Fill the shopping cart with items, the current shopping item is skuId, We also need to judge whether the number of available shopping item 17 buyerItem. SetSku (cartService. SelectSkuById (buyerItem. GetSku (). The getId ())); If (buyeritem.getAmount () > buyeritem.getsku ().getstock ()) {buyeritem.setishave (false); 22 flag = false; 23 } 24 if (! Model. AddAttribute ("buyerCart", buyerCart); 27 return "cart"; 28}} else {30} 29 31 / / shopping cart no commodities 32 / / no: 1 > the original shopping cart page refresh (no goods shopping cart page) 33 return "redirect: / shopping/toCart"; 34} 35 36 37 //3 The next page is displayed. 38 return "order"; 39}Copy the code
Take out the specified shopping cart, because we will check the goods we need to buy on the shopping cart details page before settlement, so the settlement is based on the checked goods. BuyerCart buyerCart = cartService.selectBuyerCartFromRedisBySkuIds(skuIds, username);
Remove specified items from shopping cart:
1 / / removed from the shopping cart specified goods 2 public BuyerCart selectBuyerCartFromRedisBySkuIds (String [] skuIds, String username){ 3 BuyerCart buyerCart = new BuyerCart(); Redis = skuId (key), amount (value) String> hgetAll = jedis.hgetAll("buyerCart:"+username); 6 if (null ! = hgetAll && hgetAll.size() > 0) { 7 Set<Entry<String, String>> entrySet = hgetAll.entrySet(); 8 for (Entry<String, String> entry : entrySet) { 9 for (String skuId : skuIds) { 10 if (skuId.equals(entry.getKey())) { 11 //entry.getKey(): skuId 12 Sku sku = new Sku(); 13 sku.setId(Long.parseLong(entry.getKey())); 14 BuyerItem buyerItem = new BuyerItem(); 15 buyerItem.setSku(sku); 16 //entry.getValue(): amount 17 buyerItem.setAmount(Integer.parseInt(entry.getValue())); 19 buyercart. addItem(buyerItem); 20 } 21 } 22 } 23 } 24 25 return buyerCart; 26}Copy the code
1) Refresh the shopping cart details page to display the status of the goods that are out of stock as long as one of them is out of stock.
2) Refresh the current page when shopping cart is loaded.
There are only so many things in the shopping cart. You are welcome to point out any mistakes you may not be able to explain. If it is helpful to you, please click a like to support it, thank you ~