1 購物車
1.1 業務分析
當使用者點選購物車按鈕時,應該跳轉到購物車清單頁面

頁面名稱: cart.jsp
頁面資料: ${cartList}
1.2 建立購物Cart POJO
package com.jt.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.experimental.Accessors;
@TableName("tb_cart")
@Data
@Accessors(chain = true)
public class Cart extends BasePojo{
@TableId(type = IdType.AUTO) //主鍵自增
private Long id; //購物車Id号
private Long userId; //使用者Id号
private Long itemId; //商品id号
private String itemTitle; //商品标題
private String itemImage; //商品圖檔資訊
private Long itemPrice;
private Integer num;
}
1.3 建立jt-cart項目
1.3.1 建立項目
1.3.2 添加繼承依賴插件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>jt-cart</artifactId>
<parent>
<artifactId>jt2007</artifactId>
<groupId>com.jt</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<!--3.依賴工具API-->
<dependencies>
<dependency>
<groupId>com.jt</groupId>
<artifactId>jt-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<!--4.添加maven插件-->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
1.3.3 購物車項目結構
1.4 購物車業務實作
1.4.1 購物車清單展現
(1)編輯CartController
package com.jt.controller;
import com.alibaba.dubbo.config.annotation.Reference;
import com.jt.pojo.Cart;
import com.jt.service.DubboCartService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
@Controller
@RequestMapping("/cart")
public class CartController {
@Reference(check = false)
private DubboCartService cartService;
/**
* 業務描述: 展現購物車清單頁面,同時查詢購物車資料
* url: http://www.jt.com/cart/show.html
* 參數: userId=7L
* 傳回值: 頁面邏輯名稱 cart.jsp
* 頁面取值: ${cartList}
*/
@RequestMapping("/show")
public String show(Model model){
Long userId = 7L; //暫時寫死
List<Cart> cartList = cartService.findCartListByUserId(userId);
model.addAttribute("cartList",cartList);
return "cart";
}
}
(2)編輯CartService
package com.jt.service;
import com.alibaba.dubbo.config.annotation.Service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jt.mapper.CartMapper;
import com.jt.pojo.Cart;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
@Service(timeout = 3000)
public class DubboCartServiceImpl implements DubboCartService{
@Autowired
private CartMapper cartMapper;
@Override
public List<Cart> findCartListByUserId(Long userId) {
QueryWrapper<Cart> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("user_id", userId);
return cartMapper.selectList(queryWrapper);
}
}
(3)頁面效果展示
1.4.2 購物車數量的修改
(1)頁面url分析
頁面JS分析
(2)編輯CartController
/**
* 業務描述:
* 完成購物車數量的修改操作
* url位址: http://www.jt.com/cart/update/num/1474392004/4
* 參數: restFul風格
* 傳回值: void
*/
@RequestMapping("/update/num/{itemId}/{num}")
@ResponseBody //讓ajax程式結束
public void updateNum(Cart cart){//springmvc 針對restFul提供的功能 名稱和屬性一緻
Long userId = 7L;
cart.setUserId(userId);
cartService.updateCartNum(cart);
}
(3)編輯CartService
/**
* Sql: update tb_cart set num=#{num},updated=#{updated}
* where user_id=#{userId} and item_id = #{itemId}
* @param cart
*/
@Override
public void updateCartNum(Cart cart) {
Cart cartTemp = new Cart();
cartTemp.setNum(cart.getNum());
QueryWrapper<Cart> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("user_id", cart.getUserId())
.eq("item_id", cart.getItemId());
cartMapper.update(cartTemp,queryWrapper);
}
1.4.3 購物車删除
(1)頁面分析
業務邏輯: 當删除購物車時,應該删除資料庫記錄,之後将頁面重定向到購物車清單頁面。
(2)編輯CartController
/**
* 實作購物車删除操作
* 1.url位址: http://www.jt.com/cart/delete/1474392004.html
* 2.參數: 1474392004 itemId
* 3.傳回值: String 重定向到清單頁面
*/
@RequestMapping("/delete/{itemId}")
public String deleteCart(Cart cart){
Long userId = 7L;
cart.setUserId(userId);
cartService.deleteCart(cart);
return "redirect:/cart/show.html";
}
(3)編輯CartService
@Override
public void deleteCart(Cart cart) { //userId/itemId
cartMapper.delete(new QueryWrapper<>(cart));
//根據對象中不為null的屬性當做where條件.
}
1.4.4 購物車新增
(1)業務說明
業務說明: 當購物車點選新增時,需要重定向到購物車清單頁面. 完成購物車"新增""
注意事項: 如果使用者重複添加購物車.則隻做購物車數量的更新,如果購物車沒有記錄,則新增資料。
參數接收:
(2)編輯CartController
/**
* 購物車新增操作
* url位址:http://www.jt.com/cart/add/1474391990.html
* url參數: 購物車屬性資料
* 傳回值: 重定向到購物車清單頁面
*/
@RequestMapping("/add/{itemId}")
public String addCart(Cart cart){
Long userId = 7L;
cart.setUserId(userId);
cartService.addCart(cart);
return "redirect:/cart/show.html";
}
(3)編輯CartService
/**
* 如果購物車已存在,則更新數量,否則新增.
* 如何判斷購物車資料是否存在 userId itemId
*
* @param cart
*/
@Override
public void addCart(Cart cart) {
//1.查詢購物車資訊 userId,itemId
QueryWrapper<Cart> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("user_id", cart.getUserId());
queryWrapper.eq("item_id",cart.getItemId());
Cart cartDB = cartMapper.selectOne(queryWrapper);
if(cartDB == null){
//第一次新增購物車
cartMapper.insert(cart);
}else{
//使用者已經加購,更新數量
int num = cartDB.getNum() + cart.getNum();
Cart cartTemp = new Cart();
cartTemp.setNum(num).setId(cartDB.getId());
cartMapper.updateById(cartTemp);
}
}
1.4.5 權限控制
需求: 如果使用者不登入,則不允許通路購物車清單頁面,如果沒有登入則應該重定向到使用者登入頁面。
(1)攔截器工作原理
(2)編輯攔截器配置
package com.jt.config;
import com.jt.interceptor.UserInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class MvcConfigurer implements WebMvcConfigurer{
//開啟比對字尾型配置
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
configurer.setUseSuffixPatternMatch(true);
}
//配置攔截器政策
@Autowired
private UserInterceptor userInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(userInterceptor)
.addPathPatterns("/cart/**","/order/**");
}
}
(3)編輯攔截器
說明:通過攔截器動态擷取userId
package com.jt.interceptor;
import com.jt.pojo.User;
import com.jt.util.ObjectMapperUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import redis.clients.jedis.JedisCluster;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
public class UserInterceptor implements HandlerInterceptor {
@Autowired
private JedisCluster jedisCluster;
/**
* 參數介紹:
* @param1 request 使用者請求對象
* @param2 response 伺服器響應對象
* @param3 handler 目前處理器本身
* @return Boolean true 請求放行 false 請求攔截 一般配合重定向使用
* @throws Exception
* 如果使用者不登入則重定向到登入頁面
*
* 需求: 如何判斷使用者是否登入?
* 依據: 1.根據cookie 2.判斷redis
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String ticket = null;
//1.判斷cookie中是否有記錄
Cookie[] cookies = request.getCookies();
if(cookies !=null && cookies.length>0){
for (Cookie cookie : cookies){
if("JT_TICKET".equals(cookie.getName())){
ticket = cookie.getValue();
break;
}
}
}
//2.判斷cookie資料是否有效
if(!StringUtils.isEmpty(ticket)){
if(jedisCluster.exists(ticket)){
String userJSON = jedisCluster.get(ticket);
User user = ObjectMapperUtil.toObject(userJSON, User.class);
//3.利用request對象進行資料的傳遞 request對象是最為常用的傳遞參數的媒介.
request.setAttribute("JT_USER", user);
return true; //表示使用者已經登入.
}
}
//重定向到使用者登入頁面
response.sendRedirect("/user/login.html");
return false;
}
}
(4)動态擷取UserID