购物车(完)----Day17

1.购物车操作

1.1 删除购物车

1.1.1编辑jt-web 中的CartController

根据itemId和userId删除购物车

		/**
	 * 业务:删除购物车操作
	 * url地址: http://www.jt.com/cart/delete/562379.html
	 * 参数问题: 562379
	 * 返回值结果: 重定向到购物车列表页面
	 */
	@RequestMapping("delete/{itemId}")
	public String deleteCart(@PathVariable Long itemId) {
		
		Long userId = 7L;
		Cart cart = new Cart();
		cart.setUserId(userId);
		cart.setItemId(itemId);
		cartService.deleteCart(cart);
		return "redirect:/cart/show.html"; //维护伪静态策略
	}

在Cart的CartService中添加删除代码

@Override
	public void deleteCart(Cart cart) {
		
		//让对象中不为null的属性充当where条件
		QueryWrapper<Cart> queryWrapper = new QueryWrapper<>(cart);
		cartMapper.delete(queryWrapper);
	}

2.权限控制

  • 业务分析
    当用户未登录时,不允许访问敏感操作. 例如访问购物车/订单等系统.如何实现???
    技术: 拦截器技术. shiro

2.1 SpringMVC中拦截器定义

拦截器一般只拦截web页面资源的请求.
拦截器处理的流程图:
在这里插入图片描述

2.1.1拦截器配置在MvcConfigurer 中加个配置

	@Configuration
public class MvcConfigurer implements WebMvcConfigurer{
	
	@Autowired
	private UserInterceptor userInterceptor;
	
	//开启匹配后缀型配置    
	@Override
	public void configurePathMatch(PathMatchConfigurer configurer) { 
		configurer.setUseSuffixPatternMatch(true);
	}
	 
	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		
		//   /** 表示拦截多级目录   /*  只拦截一级目录
		registry.addInterceptor(userInterceptor)
				.addPathPatterns("/cart/**","/order/**");
	}
}

  • 编辑拦截器业务
	@Component  //将对象交给容器管理
public class UserInterceptor implements HandlerInterceptor{
	
	@Autowired
	private JedisCluster jedisCluster;
	/**
	 * 目的: 如果用户不登录,则不允许访问权限相关业务.
	 * 返回值: 
	 * 		 true:表示放行 
	 * 		 false: 表示拦截  一般配置重定向使用.
	 * 注意事项:必须添加拦截器策略.
	 * 业务说明:
	 * 	 用户如果已经登录,则放行,反正拦截
	 *  
	 * 如何判断用户是否登录:
	 * 	1.判断客户端是否有指定的Cookie    true
	 * 	2.应该获取cookie中的值  去redis中校验是否存在.  true
	 *  如果上述条件都满足,则应该放行请求.
	 * 
	 */
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		//业务实现  1.获取cookie
		Cookie[] cookies = request.getCookies();
		if(cookies !=null && cookies.length>0) {
			for (Cookie cookie : cookies) {
				if("JT_TICKET".equals(cookie.getName())){
					//如果equals则说明cookie是存在的.
					String ticket = cookie.getValue();
					//2.redis中是否有该记录  如果有记录则放行请求.
					if(jedisCluster.exists(ticket)) {
						//说明数据以及存在.可以放行
						return true;
					}
				}
			}
		}
		
		//重定向到用户登录页面
		response.sendRedirect("/user/login.html");
		return false;
	}
}

2.2 动态获取userId

如何动态获取userId

2.2.1动态获取User信息

	package com.jt.interceptor;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import com.jt.pojo.User;
import com.jt.util.ObjectMapperUtil;

import redis.clients.jedis.JedisCluster;
//mvc提供的对外的拦截器接口.
@Component  //将对象交给容器管理
public class UserInterceptor implements HandlerInterceptor{
	
	@Autowired
	private JedisCluster jedisCluster;
	/**
	 * 目的: 如果用户不登录,则不允许访问权限相关业务.
	 * 返回值: 
	 * 		 true:表示放行 
	 * 		 false: 表示拦截  一般配置重定向使用.
	 * 注意事项:必须添加拦截器策略.
	 * 业务说明:
	 * 	 用户如果已经登录,则放行,反正拦截
	 *  
	 * 如何判断用户是否登录:
	 * 	1.判断客户端是否有指定的Cookie    true
	 * 	2.应该获取cookie中的值  去redis中校验是否存在.  true
	 *  如果上述条件都满足,则应该放行请求.
	 * 
	 */
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		//业务实现  1.获取cookie
		Cookie[] cookies = request.getCookies();
		if(cookies !=null && cookies.length>0) {
			for (Cookie cookie : cookies) {
				if("JT_TICKET".equals(cookie.getName())){
					//如果equals则说明cookie是存在的.
					String ticket = cookie.getValue();
					//2.redis中是否有该记录  如果有记录则放行请求.
					if(jedisCluster.exists(ticket)) {
						
						//3.动态获取用户json信息
						String userJSON = jedisCluster.get(ticket);
						User user = ObjectMapperUtil.toObject(userJSON, User.class);
						//利用request对象传递用户信息.
						request.setAttribute("JT_USER", user);
						//说明数据以及存在.可以放行
						return true;
					}
				}
			}
		}
		
		//重定向到用户登录页面
		response.sendRedirect("/user/login.html");
		return false;
	}
}


2.2.2 CartController 动态获取userId(jt-web)

	@RequestMapping("show")
	public String show(Model model,HttpServletRequest request) {
		User user =(User) request.getAttribute("JT_USER");
	
		//1.获取userId	利用单点登入的方式获取userId   暂时写死
		Long userId =user.getId();
		//2.根据userId查询公务车数据
		List<Cart> cartList =cartService.findCartListByUserId(userId);
		//利用model对象将对象数据填充到域对象request域中
		model.addAttribute("cartList",cartList);
		return "cart";
	}

3.订单确认页面跳转

  • 3.1业务分析
    说明:http://www.jt.com/order/create.html 当用户点击提交订单时.应该跳转到订单确认页面.之后添加收件人信息.
    订单确认页面名称:order-cart.jsp

3.1 jt-web编辑OrderController

package com.jt.controllor;

import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import com.alibaba.dubbo.config.annotation.Reference;
import com.jt.pojo.Cart;
import com.jt.pojo.User;
import com.jt.service.DubboCartService;

@Controller
@RequestMapping("/order")
public class OrderController {

	@Reference(check = false)
	private DubboCartService cartService;
	/**
	 * 跳转到订单确认页面 http://www.jt.com/order/create.html
	 * 业务逻辑: 根据userId,之后查询购物车记录信息.之后在页面中展现购物车数据.
	 * 页面取值: ${carts}
	 */
	@RequestMapping("/create")
	public String create(HttpServletRequest request,Model model) {
		
		User user = (User) request.getAttribute("JT_USER");
		long userId = user.getId();
		List<Cart> cartList = cartService.findCartListByUserId(userId);
		model.addAttribute("carts", cartList);
		return "order-cart";
	}
 
}

效果
在这里插入图片描述

4.订单业务结构表设计

4.1 表结构设计

在这里插入图片描述

4.2 导入订单pojo对象

  • 在jt-common中添加POJO
    Order
package com.jt.pojo;


import java.util.Date;
import java.util.List;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;

import lombok.Data;
import lombok.experimental.Accessors;

@TableName("tb_order")
@Data
@Accessors(chain=true)
public class Order extends BasePojo{
	@TableField(exist=false)	//入库操作忽略该字段
	private OrderShipping orderShipping;
								//封装订单商品信息  一对多
	@TableField(exist=false)	//入库操作忽略该字段
	private List<OrderItem> orderItems;
	
	//@TableId
    private String orderId;
    private String payment;
    private Integer paymentType;
    private String postFee;
    private Integer status;
    private Date paymentTime;
    private Date consignTime;
    private Date endTime;
    private Date closeTime;
    private String shippingName;
    private String shippingCode;
    private Long userId;
    private String buyerMessage;
    private String buyerNick;
    private Integer buyerRate;

}

OrderItem

package com.jt.pojo;


import java.util.Date;
import java.util.List;

import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;

import lombok.Data;
import lombok.experimental.Accessors;
@TableName("tb_order_item")
@Data
@Accessors(chain=true)
public class OrderItem extends BasePojo{
	
	@TableId
    private String itemId;
	//@TableId	
    private String orderId;
    private Integer num;
    private String title;
    private Long price;
    private Long totalFee;
    private String picPath;
}

OrderShipping

package com.jt.pojo;

import java.util.Date;
import java.util.List;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;

import lombok.Data;
import lombok.experimental.Accessors;
@TableName("tb_order_shipping")
@Data
@Accessors(chain=true)
public class OrderShipping extends BasePojo{
	
	@TableId
    private String orderId;
    private String receiverName;
    private String receiverPhone;
    private String receiverMobile;
    private String receiverState;
    private String receiverCity;
    private String receiverDistrict;
    private String receiverAddress;
    private String receiverZip;
}

4.3 创建JT-ORDER项目

  • 创建jt-order(jar)项目
  • 导入pom
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.jt</groupId>
    <artifactId>jt</artifactId>
    <version>0.0.1-SNAPSHOT</version>
  </parent>
  <artifactId>jt-order</artifactId>
	<dependencies>
		<dependency>
			<groupId>com.jt</groupId>
			<artifactId>jt-common</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>
	</dependencies>
	<build>
		<!--SpringBoot项目必须添加maven插件插件 -->
		<plugins>
			<plugin>
				<!--SpringBoot自动的导入maven插件的依赖包. 主要负责项目打包/更新/maven等相关操作 -->
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
</project>
  • 创建如下类
    在这里插入图片描述
  • 编辑yml
server:
  port: 8095
  servlet:
    context-path: /
spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    #如果需要项目发布,则数据库地址必须配置远程数据库
    url: jdbc:mysql://127.0.0.1:3306/jtdb?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
    username: root
    password: root
  
  #配置视图解析器
  mvc:
    view:
      prefix: /WEB-INF/views/
      suffix: .jsp
      
#mybatis-plush配置
mybatis-plus:
  type-aliases-package: com.jt.pojo
  mapper-locations: classpath:/mybatis/mappers/*.xml
  configuration:
    map-underscore-to-camel-case: true

#日志记录 输出数据库的日志信息.
logging:
  config: classpath:logging-config.xml
  level: 
    com.jt.mapper: debug
    
dubbo:
  scan:
    basePackages: com.jt    #指定dubbo的包路径
  application:
    name: provider-order     #指定服务名称(必须指定)
  registry:
    address: zookeeper://192.168.126.129:2181?backup=192.168.126.129:2182,192.168.126.129:2183,192.168.126.129:2184,192.168.126.129:2185
  protocol:  #指定协议
    name: dubbo  #使用dubbo协议(tcp-ip)  web-controller直接调用sso-Service
    port: 20883 #每个服务都应该有自己特定的端口  

5.SpringMVC的页面与后端数据传递方式.

html页面信息:

<html>
<input  id="name" name="name"/>
<input  id="age" name="age"/>
</html>
  • 简单模式
    UserController后端接收:
    利用request对象的取值和赋值的方式实现操作
public xxxxx   saveUser(String name,Integer age){
}
  • 利用对象的方式封装
    UserController后端接收:
    1.利用request对象取赋值操作. 2.利用对象的set方法,为对象的属性赋值.
public xxxxx   saveUser(User user){
}
  • 为对象的引入赋值
    说明:如果按照下列的方式提交.,则会出现重名提交的问题.
    解决方案: 可以利用为对象的引用赋值的操作.
<html>
	<input  id="name" name="name"/>  
	<input  id="age" name="age"/>
	<input  id="name" name="dog.name" value="哮天犬"/>  
	<input  id="age" name="dog.age" value="3"/>  	
</html>

UserController后端接收:

public class User{
	private String name;
	private Integer age;
	private Dog   dog;    //对象的引用.
}
public class Dog{
	private String name;
	private Integer age;
}

//利用;User对象实现了User的数据与Dog的数据的获取.
 public xxxxx   saveUser(User user){		
 }

猜你喜欢

转载自blog.csdn.net/SkyCloud_/article/details/107621918
今日推荐