1. 购物车业务实现

1.1 购物车列表展现

1.1.1 编辑CartController

  1. package com.jt.controller;
  2. import com.alibaba.dubbo.config.annotation.Reference;
  3. import com.jt.pojo.Cart;
  4. import com.jt.service.DubboCartService;
  5. import org.springframework.stereotype.Controller;
  6. import org.springframework.ui.Model;
  7. import org.springframework.web.bind.annotation.RequestMapping;
  8. import java.util.List;
  9. @Controller
  10. @RequestMapping("/cart")
  11. public class CartController {
  12. @Reference(check = false)
  13. private DubboCartService cartService;
  14. /**
  15. * 业务描述: 展现购物车列表页面,同时查询购物车数据
  16. * url: http://www.jt.com/cart/show.html
  17. * 参数: userId=7L
  18. * 返回值: 页面逻辑名称 cart.jsp
  19. * 页面取值: ${cartList}
  20. */
  21. @RequestMapping("/show")
  22. public String show(Model model){
  23. Long userId = 7L; //暂时写死
  24. List<Cart> cartList = cartService.findCartListByUserId(userId);
  25. model.addAttribute("cartList",cartList);
  26. return "cart";
  27. }
  28. }

1.1.2 编辑CartService

  1. package com.jt.service;
  2. import com.alibaba.dubbo.config.annotation.Service;
  3. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  4. import com.jt.mapper.CartMapper;
  5. import com.jt.pojo.Cart;
  6. import org.springframework.beans.factory.annotation.Autowired;
  7. import java.util.List;
  8. @Service(timeout = 3000)
  9. public class DubboCartServiceImpl implements DubboCartService{
  10. @Autowired
  11. private CartMapper cartMapper;
  12. @Override
  13. public List<Cart> findCartListByUserId(Long userId) {
  14. QueryWrapper<Cart> queryWrapper = new QueryWrapper<>();
  15. queryWrapper.eq("user_id", userId);
  16. return cartMapper.selectList(queryWrapper);
  17. }
  18. }

1.1.3 页面效果展现

19-京淘项目购物车操作 订单查询 - 图1

1.2 购物车数量的修改

1.2.1 页面URL分析

1.页面URL分析
19-京淘项目购物车操作 订单查询 - 图2
2.商品的参数 在url地址中 RESTFul风格.
3.页面JS分析
19-京淘项目购物车操作 订单查询 - 图3

1.2.2 编辑CartController

  1. /**
  2. * 业务描述:
  3. * 完成购物车数量的修改操作
  4. * url地址: http://www.jt.com/cart/update/num/1474392004/4
  5. * 参数: restFul风格
  6. * 返回值: void
  7. */
  8. @RequestMapping("/update/num/{itemId}/{num}")
  9. @ResponseBody //让ajax程序结束
  10. public void updateNum(Cart cart){//springmvc 针对restFul提供的功能 名称和属性一致
  11. Long userId = 7L;
  12. cart.setUserId(userId);
  13. cartService.updateCartNum(cart);
  14. }

1.2.2 编辑CartService

  1. /**
  2. * Sql: update tb_cart set num=#{num},updated=#{updated}
  3. * where user_id=#{userId} and item_id = #{itemId}
  4. * @param cart
  5. */
  6. @Override
  7. public void updateCartNum(Cart cart) {
  8. Cart cartTemp = new Cart();
  9. cartTemp.setNum(cart.getNum());
  10. QueryWrapper<Cart> queryWrapper = new QueryWrapper<>();
  11. queryWrapper.eq("user_id", cart.getUserId())
  12. .eq("item_id", cart.getItemId());
  13. cartMapper.update(cartTemp,queryWrapper);
  14. }

1.3 购物车删除

1.3.1 页面分析

业务逻辑: 当删除购物车时,应该删除数据库记录,之后将页面重定向到购物车列表页面.
19-京淘项目购物车操作 订单查询 - 图4

1.3.2 编辑CartController

  1. /**
  2. * 实现购物车删除操作
  3. * 1.url地址: http://www.jt.com/cart/delete/1474392004.html
  4. * 2.参数: 1474392004 itemId
  5. * 3.返回值: String 重定向到列表页面
  6. */
  7. @RequestMapping("/delete/{itemId}")
  8. public String deleteCart(Cart cart){
  9. Long userId = 7L;
  10. cart.setUserId(userId);
  11. cartService.deleteCart(cart);
  12. return "redirect:/cart/show.html";
  13. }

1.3.3 编辑CartService

  1. @Override
  2. public void deleteCart(Cart cart) { //userId/itemId
  3. cartMapper.delete(new QueryWrapper<>(cart));
  4. //根据对象中不为null的属性当做where条件.
  5. }

1.4 购物车新增

1.4.1 业务说明

业务说明: 当购物车点击新增时,需要重定向到购物车列表页面. 完成购物车”新增””
注意事项: 如果用户重复添加购物车.则只做购物车数量的更新,如果购物车没有记录,则新增数据.
19-京淘项目购物车操作 订单查询 - 图5
2).参数接收
19-京淘项目购物车操作 订单查询 - 图6

1.4.2 编辑CartController

  1. /**
  2. * 购物车新增操作
  3. * url地址:http://www.jt.com/cart/add/1474391990.html
  4. * url参数: 购物车属性数据
  5. * 返回值: 重定向到购物车列表页面
  6. */
  7. @RequestMapping("/add/{itemId}")
  8. public String addCart(Cart cart){
  9. Long userId = 7L;
  10. cart.setUserId(userId);
  11. cartService.addCart(cart);
  12. return "redirect:/cart/show.html";
  13. }

1.4.3 编辑CartService

  1. /**
  2. * 如果购物车已存在,则更新数量,否则新增.
  3. * 如何判断购物车数据是否存在 userId itemId
  4. *
  5. * @param cart
  6. */
  7. @Override
  8. public void addCart(Cart cart) {
  9. //1.查询购物车信息 userId,itemId
  10. QueryWrapper<Cart> queryWrapper = new QueryWrapper<>();
  11. queryWrapper.eq("user_id", cart.getUserId());
  12. queryWrapper.eq("item_id",cart.getItemId());
  13. Cart cartDB = cartMapper.selectOne(queryWrapper);
  14. if(cartDB == null){
  15. //第一次新增购物车
  16. cartMapper.insert(cart);
  17. }else{
  18. //用户已经加购,更新数量
  19. int num = cartDB.getNum() + cart.getNum();
  20. Cart cartTemp = new Cart();
  21. cartTemp.setNum(num).setId(cartDB.getId());
  22. cartMapper.updateById(cartTemp);
  23. }
  24. }

1.5 权限控制

需求: 如果用户不登录,则不允许访问购物车列表页面,如果没有登录则应该重定向到用户登录页面.

1.5.1 拦截器工作原理

19-京淘项目购物车操作 订单查询 - 图7

1.5.2 编辑拦截器配置

  1. package com.jt.config;
  2. import com.jt.interceptor.UserInterceptor;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.context.annotation.Configuration;
  5. import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
  6. import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
  7. import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
  8. @Configuration
  9. public class MvcConfigurer implements WebMvcConfigurer{
  10. //开启匹配后缀型配置
  11. @Override
  12. public void configurePathMatch(PathMatchConfigurer configurer) {
  13. configurer.setUseSuffixPatternMatch(true);
  14. }
  15. //配置拦截器策略
  16. @Autowired
  17. private UserInterceptor userInterceptor;
  18. @Override
  19. public void addInterceptors(InterceptorRegistry registry) {
  20. registry.addInterceptor(userInterceptor)
  21. .addPathPatterns("/cart/**","/order/**");
  22. }
  23. }

1.5.3 编辑拦截器

说明:通过拦截器动态获取userId

  1. package com.jt.interceptor;
  2. import com.jt.pojo.User;
  3. import com.jt.util.ObjectMapperUtil;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.stereotype.Component;
  6. import org.springframework.util.StringUtils;
  7. import org.springframework.web.servlet.HandlerInterceptor;
  8. import redis.clients.jedis.JedisCluster;
  9. import javax.servlet.http.Cookie;
  10. import javax.servlet.http.HttpServletRequest;
  11. import javax.servlet.http.HttpServletResponse;
  12. @Component
  13. public class UserInterceptor implements HandlerInterceptor {
  14. @Autowired
  15. private JedisCluster jedisCluster;
  16. /**
  17. * 参数介绍:
  18. * @param1 request 用户请求对象
  19. * @param2 response 服务器响应对象
  20. * @param3 handler 当前处理器本身
  21. * @return Boolean true 请求放行 false 请求拦截 一般配合重定向使用
  22. * @throws Exception
  23. * 如果用户不登录则重定向到登录页面
  24. *
  25. * 需求: 如何判断用户是否登录?
  26. * 依据: 1.根据cookie 2.判断redis
  27. */
  28. @Override
  29. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
  30. String ticket = null;
  31. //1.判断cookie中是否有记录
  32. Cookie[] cookies = request.getCookies();
  33. if(cookies !=null && cookies.length>0){
  34. for (Cookie cookie : cookies){
  35. if("JT_TICKET".equals(cookie.getName())){
  36. ticket = cookie.getValue();
  37. break;
  38. }
  39. }
  40. }
  41. //2.判断cookie数据是否有效
  42. if(!StringUtils.isEmpty(ticket)){
  43. if(jedisCluster.exists(ticket)){
  44. String userJSON = jedisCluster.get(ticket);
  45. User user = ObjectMapperUtil.toObject(userJSON, User.class);
  46. //3.利用request对象进行数据的传递 request对象是最为常用的传递参数的媒介.
  47. request.setAttribute("JT_USER", user);
  48. return true; //表示用户已经登录.
  49. }
  50. }
  51. //重定向到用户登录页面
  52. response.sendRedirect("/user/login.html");
  53. return false;
  54. }
  55. }

1.6测试

2.总结

本节内容主要是在Dubbo基础上,实现项目的购物车系统,订单系统,完善项目功能。