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){
}