2006-京淘Day20

it2025-07-21  11

1. 购物车删除操作

1.1 页面分析

1.2 编辑CartController

/** * 购物车删除操作 * url地址: http://www.jt.com/cart/delete/562379.html * 参数: 获取itemId * 返回值: 重定向到购物车的展现页面 */ @RequestMapping("/delete/{itemId}") public String deleteCarts(@PathVariable Long itemId){ Long userId = 7L; cartService.deleteCarts(userId,itemId); return "redirect:/cart/show.html"; }

1.3 编辑CartService

@Override public void deleteCarts(Long userId, Long itemId) { QueryWrapper<Cart> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("user_id", userId); queryWrapper.eq("item_id", itemId); cartMapper.delete(queryWrapper); }

2. 京淘权限实现

2.1 业务需求

当用户进行敏感操作时,必须要求用户先登录之后才可以访问后端服务器. 例如京东商城… 使用技术: 1.AOP 2.拦截器 :拦截用户的请求

2.2 定义京淘拦截器

2.2.1 SpringMVC调用原理图

2.2.2 SpringMVC拦截器工作原理

2.2.3 配置拦截器

@Component //spring容器管理对象 public class UserInterceptor implements HandlerInterceptor { @Autowired private JedisCluster jedisCluster; //Spring版本升级 4 必须实现所有的方法 spring 5 只需要重写指定的方法即可. /** * 需求: 拦截/cart开头的所有的请求进行拦截.,并且校验用户是否登录..... * 拦截器选择: preHandler * 如何判断用户是否登录: 1.检查cookie信息 2.检查Redis中是否有记录. * true : 请求应该放行 * false: 请求应该拦截 则配合重定向的语法实现页面跳转到登录页面 使得程序流转起来 */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //1.判断用户是否登录 检查cookie是否有值 String ticket = CookieUtil.getCookieValue(request,"JT_TICKET"); //2.校验ticket if(!StringUtils.isEmpty(ticket)){ //3.判断redis中是否有值. if(jedisCluster.exists(ticket)){ //4.动态获取json信息 String userJSON = jedisCluster.get(ticket); User user = ObjectMapperUtil.toObj(userJSON,User.class); request.setAttribute("JT_USER",user); return true; } } response.sendRedirect("/user/login.html"); return false; } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { //销毁数据 request.removeAttribute("JT_USER"); } }

2.2.4 动态获取UserId

2.3 ThreadLocal介绍

2.3.1 ThreadLocal作用

名称: 本地线程变量 作用: 可以在同一个线程内,实现数据的共享.

2.3.2 ThreadLocal入门案例

private ThreadLocal<Integer> threadLocal = new ThreadLocal<>(); public void a(){ int a = 100; threadLocal.set(a); b(); } public void b(){ int a = threadLocal.get(); int b = 100*a; }

2.3.3 编辑ThreadLocal工具API

public class UserThreadLocal { //static不会影响影响线程 threadLocal创建时跟随线程. //private static ThreadLocal<Map<k,v>> threadLocal = new ThreadLocal<>(); private static ThreadLocal<User> threadLocal = new ThreadLocal<>(); public static void set(User user){ threadLocal.set(user); } public static User get(){ return threadLocal.get(); } public static void remove(){ threadLocal.remove(); } }

2.3.4 重构User拦截器

2.3.5 动态获取UserId

3.京淘订单模块

3.1 订单表设计

3.2 创建订单项目

3.2.1 创建项目

3.2.2 添加继承依赖

<!--2.添加依赖信息--> <dependencies> <!--依赖实质依赖的是jar包文件--> <dependency> <groupId>com.jt</groupId> <artifactId>jt-common</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> <!--3.添加插件--> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>

3.2.3 添加POJO

删除orderItem的主键标识

3.2.4 构建jt-order项目

订单项目代码结构如下

3.3 订单确认页面跳转

3.3.1 url分析

3.3.2 编辑OrderController

package com.jt.controller; import com.alibaba.dubbo.config.annotation.Reference; import com.jt.pojo.Cart; import com.jt.service.DubboCartService; import com.jt.service.DubboOrderService; import com.jt.thread.UserThreadLocal; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import java.util.List; @Controller @RequestMapping("/order") public class OrderController { @Reference(timeout = 3000,check = false) private DubboOrderService orderService; @Reference(timeout = 3000,check = false) private DubboCartService cartService; /** * 订单页面跳转 * url: http://www.jt.com/order/create.html * 页面取值: ${carts} */ @RequestMapping("/create") public String create(Model model){ //1.根据userId查询购物车信息 Long userId = UserThreadLocal.get().getId(); List<Cart> cartList = cartService.findCartListByUserId(userId); model.addAttribute("carts",cartList); return "order-cart"; } }

3.3.3 编辑OrderService

@Override public List<Cart> findCartListByUserId(Long userId) { QueryWrapper<Cart> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("user_id", userId); return cartMapper.selectList(queryWrapper); }

3.3.4 页面效果展现

3.4 关于SpringMVC参数提交问题说明

3.4.1 简单参数传参问题

1.页面url标识

2.Controller中的方法 public void xxx(String name,int age){

}

3.4.2 使用对象方法接收参数

1.页面url标识 2.Controller中的方法 public void xxx(User user){

} public class User{ private Integer name; private String age; }

3.4.3 使用对象的引用为参数赋值

难点: 属性的重名提交问题… 解决思路: 可以采用对象引用的方式为属性赋值.

<input name="name" value="二郎神" /> <input name="age" value="3000" /> <input name="dog.name" value="哮天犬" /> <input name="dog.age" value="8000" />

2.Controller中的方法

public void xxx(User user){ } public class Dog{ private String name; private Integer age; } public class User{ private String name; private Integer age; private Dog dog; }

3.5 关于订单提交

3.5.1 页面URL说明

3.5.2 请求参数

3.5.3 页面JS解析

jQuery.ajax( { type : "POST", dataType : "json", url : "/order/submit", data : $("#orderForm").serialize(), // data: {"key":"value","key2":"value2".....} // data: id=1&name="xxx"&age=18...... cache : false, success : function(result) { if(result.status == 200){ location.href = "/order/success.html?id="+result.data; }else{ $("#submit_message").html("订单提交失败,请稍后重试...").show(); } }, error : function(error) { $("#submit_message").html("亲爱的用户请不要频繁点击, 请稍后重试...").show(); } });

3.5.3 编辑OrderController

/** * 订单提交 * url: http://www.jt.com/order/submit * 参数: 整个form表单 * 返回值: SysResult对象 携带返回值orderId * 业务说明: * 当订单入库之后,需要返回orderId.让用户查询. */ @RequestMapping("/submit") @ResponseBody public SysResult saveOrder(Order order){ Long userId = UserThreadLocal.get().getId(); order.setUserId(userId); String orderId = orderService.saveOrder(order); if(StringUtils.isEmpty(orderId)) return SysResult.fail(); else return SysResult.success(orderId); }

3.5.4 编辑OrderService

@Service(timeout = 3000) public class DubboOrderServiceImpl implements DubboOrderService { @Autowired private OrderMapper orderMapper; @Autowired private OrderItemMapper orderItemMapper; @Autowired private OrderShippingMapper orderShippingMapper; /** * Order{order订单本身/order物流信息/order商品信息} * 难点: 操作3张表完成入库操作 * 主键信息: orderId * @param order * @return */ @Override public String saveOrder(Order order) { //1.拼接OrderId String orderId = "" + order.getUserId() + System.currentTimeMillis(); //2.完成订单入库 order.setOrderId(orderId).setStatus(1); orderMapper.insert(order); //3.完成订单物流入库 OrderShipping orderShipping = order.getOrderShipping(); orderShipping.setOrderId(orderId); orderShippingMapper.insert(orderShipping); //4.完成订单商品入库 List<OrderItem> orderItems = order.getOrderItems(); //批量入库 sql: insert into xxx(xxx,xx,xx)values (xx,xx,xx),(xx,xx,xx).... for (OrderItem orderItem : orderItems){ orderItem.setOrderId(orderId); orderItemMapper.insert(orderItem); } System.out.println("订单入库成功!!!!"); return orderId; } }

3.6 订单成功跳转

3.6.1 页面url分析

3.6.2 编辑OrderController

/** * 实现商品查询 * 1.url地址: http://www.jt.com/order/success.html?id=71603356409924 * 2.参数说明: id 订单编号 * 3.返回值类型: success.html * 4.页面取值方式: ${order.orderId} */ @RequestMapping("/success") public String findOrderById(String id,Model model){ Order order = orderService.findOrderById(id); model.addAttribute("order",order); return "success"; }

3.6.2 编辑OrderService

@Override public Order findOrderById(String id) { //1.查询订单信息 Order order = orderMapper.selectById(id); //2.查询订单物流信息 OrderShipping orderShipping = orderShippingMapper.selectById(id); //3.查询订单商品 QueryWrapper<OrderItem> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("order_id",id); List<OrderItem> lists =orderItemMapper.selectList(queryWrapper); return order.setOrderItems(lists).setOrderShipping(orderShipping); }

3.6.3 页面效果展现

4 项目结构图

最新回复(0)