复习 cookie提取 封装成一个类
package com.jt.util;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class CookieUtil {
/**
* 该工具API主要的任务
* 1.根据cookie的名称 返回cookie对象
* 2.根据cookie的名称 返回valve的值
* 3.新增cookie方法
* 4.删除cookie方法
*/
public static Cookie getCookie(String cookieName, HttpServletRequest request){
Cookie[] cookies = request.getCookies();
if(cookies !=null && cookies.length >0) {
for (Cookie cookie : cookies) {
if (cookieName.equals(cookie.getName())) {
return cookie;
}
}
}
return null ;
}
public static String getCookieValue(String cookieName,HttpServletRequest request){
Cookie cookie = getCookie(cookieName, request);
return cookie ==null?null:cookie.getValue();
}
public static void addCookie(String cookieName, String cookieValue, String path,
String domain, int maxAge, HttpServletResponse response){
Cookie cookie = new Cookie(cookieName,cookieValue);
cookie.setPath(path);
cookie.setDomain(domain);
cookie.setMaxAge(maxAge);
response.addCookie(cookie);
}
public static void deleteCookie(String cookieName,String path,
String domain,HttpServletResponse response){
addCookie(cookieName,"",path, domain, 0, response);
}
}
上午
1.实现京淘项目权限控制
需求分析
如果用户没有进行登录操作时,访问购物车/订单等敏感操作时将不允许访问,应该重定向到系统的登录页面.
知识点:
- AOP: 对原有的方法进行扩展.在原有的基础之上提供了额外的操作. 业务控制的.Service层
- 拦截器: 控制了程序的执行轨迹.满足条件时才会执行任务. 控制的request对象/response对象 控制用户的请求.
- 数据传输. request对象 /ThreadLocal
需求分析
重定向用拦截器比较控制 请求(controller层相关)
业务逻辑层(业务操作 service层) 用aop最合适 核心功能 业务代码不能改
经过servlet对请求进行控制的话 一般用拦截器
authc 拦截 anon放行
9.25一句话 性能相关??下午
关于拦截器的说明
关于拦截器说明
1.2.1 SpringMVC程序调用流程
如上图 去管理上上图
如上图 链式结构 耦合性过高
红色框都是由handler处理器去帮助处理完成
在mvc当中 处理器就是去真正完成业务调用这个线程的名字
所以handler
只能拦截handler处理器生命周期之内 controller->service->dao->db
9.42 想再听一次 中午
default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
return true;
}
结果
拦截器工作原理
分析处理器(HandlerInterceptor) preHandle最常用
对应下面
总结
拦截用户 不登陆就不能访问 应该用preHandle
实现
上图如上上图 跳转回登陆页面
自我实现 拦截
拦截后 要跳转到的页面
页面实现
没登陆 进不了购物车 实现成功
还没完善
晚上 日后疑问回顾 为什么要将无效的cookie删掉 可以深化的点 去归纳
cookie乱加1111111111 然后刷新页面
自我实现 完善
刷新后
完美实现
拿到用户动态id 去动态获取
去到controller
session怕共用 resquest不会出现脏读 绑定了线程 一条线程一个request
自我实现 动态获取userId 就是对应用户 对应购物车的事情 没添加就没有 忘了的话自己看实现结果
package com.jt.interceptor;
import com.jt.pojo.User;
import com.jt.util.CookieUtil;
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.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//处理器拦截器
//一般在接口中定义default可以使得实现类不必重写所有的接口的方法.
@Component //将拦截器交给Spring容器管理
public class UserInterceptor implements HandlerInterceptor {
@Autowired
private JedisCluster jedisCluster;
/**
* 返回值说明:
* boolean: true 放行
* : false 拦截 一般配合重定向的方式使用
*
* 业务说明:
* 如果用户已经登录则程序放行.否则拦截
* 判断依据: 1.是否有cookie 2.redis中是否有记录.
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//1.动态获取JT_TICKET数据
String ticket = CookieUtil.getCookieValue("JT_TICKET",request);
if(!StringUtils.isEmpty(ticket)){
//2.判断redis中是否有数据
if(jedisCluster.exists(ticket)){
//4.动态获取user信息.将用户信息交给request对象传递给下一级
String userJSON = jedisCluster.get(ticket);
User user = ObjectMapperUtil.toObject(userJSON,User.class);
//当前的对象会携带当前的用户信息!!!!
request.setAttribute("JT_USER",user);
return true; //表示放行
}
//3.将无效的cookie删除.
CookieUtil.deleteCookie("JT_TICKET","/","jt.com",response);
}
//重定向到用户的登录页面.
response.sendRedirect("/user/login.html");
return false;
}
}
/**
* 1.购物车列表数据展现
* url地址: http://www.jt.com/cart/show.html
* 参数: 暂时没有
* 返回值: 页面逻辑名称 cart.jsp
* 页面取值: ${cartList}
* 应该将数据添加到域对象中 Request域 model工具API操作request对象
*
*/
@RequestMapping("/show")
public String show(Model model, HttpServletRequest request){
User user = (User) request.getAttribute("JT_USER");
Long userId = user.getId();
List<Cart> cartList = cartService.findCartListByUserId(userId);
model.addAttribute("cartList",cartList);
return "cart";
}
User user = (User) request.getAttribute("JT_USER");
Long userId = user.getId();
页面实现
admin123原有的
新注册一个
有 但不会共用??晚上回看11.03之前
每次都要在pre拦截 写两个很麻烦
考虑用ThreadLocal
request只能页面到controller 想要往下(service层) 还得自己写方法
新建
考虑内存溢出 线程问题
自我实现
key是对象(线程 比较特殊) 是地址 value是值 是数据
应用到controller层
页面实现 看看能不能像之前那样 动态获取到对象 userId
完美实现 晚上记得再去回看录像 cookie没添加物品的话 估计是无用cookie 自动生成的 有点遗忘了
自我实现 晚上去复习 上面只是大概
总结:同一线程内采用ThreadLocal
示例
假设 把ThreadLocal放在jt-common
创建订单项目
2.1 项目创建jt-order 2.1.1 创建项目
添加继承/依赖/插件
<parent>
<artifactId>jt</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<!--添加依赖项-->
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>jt-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<!--添加插件-->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
自我新建 最关键的就是 1.依赖 2.配置文件
插入3个新的pojo
依赖
src
配置文件修改
配置文件
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
protocol: #指定协议
name: dubbo #使用dubbo协议(tcp-ip) web-controller直接调用sso-Service
port: 20883 #每个服务都应该有自己特定的端口
pom依赖
<?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-order</artifactId>
<parent>
<artifactId>jt</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<!--添加依赖项-->
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>jt-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<!--添加插件-->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
运行
重新刷新下依赖 没问题了
下午
订单确认页面跳转
2.2.1 页面分析
页面的取值说明
当用户点击去结算时,应该跳转到订单确认页面 order-cart.jsp,应该展现用户的购物车相关信息.之后提交订单即可.
自我实现
脚手架
jt-web 消费者 新建订单controller
考虑request域
新增也实现成功
订单表说明
订单表
联合主键 一个商品 不能同时入库两次 不可能有两条记录
订单表注意事项
1.订单的ID号不是主键自增
2.订单状态信息由 1-6 注意状态说明
提交订单 页面分析
举例 SpringMVC中参数格式说明
2.4.1 简单参数传值问题
说明:页面传参中 name属性必须与mvc中的数据保持一致.
1.页面信息
<input type="text" name="name" value="二郎神"/>
<input type="text" name="age" value="3500"/>
2.服务端接收
public String saveUser(String name,Integer age){....}
2.4.2 利用对象的方式接收参数
1.页面信息
<input type="text" name="name" value="二郎神"/>
<input type="text" name="age" value="3500"/>
2.服务端接收
public String saveUser(User user){....}
mvc为对象的引用赋值
问题:如何解决重名提交的问题???
方案: 可以将对象进行封装,之后采用对象引用赋值的方式实现该功能.
注意事项: 属性的名称必须一致,否则赋值失败.
1.页面信息
<input type="text" name="name" value="二郎神"/>
<input type="text" name="age" value="3500"/>
<input type="text" name="dog.name" value="啸天犬"/>
<input type="text" name="dog.age" value="5000"/>
2.服务端接收
public class User {
private String name;
private Integer age;
private Dog dog;
}
public class Dog{
private String name;
private Integer age;
}
public String saveUser(User user){....}
2.4.4 订单对象定义
采用为对象引用赋值的操作. 但是该属性不属于数据库,所以需要额外的配置.
15.12 下午 晚上
订单入库
paymentType: 1
orderItems[0].itemId: 562379
orderItems[0].num: 20
orderItems[0].price: 4299000
orderItems[0].totalFee: 85980000
orderItems[0].title: 三星
orderItems[0].picPath: http://image.taotao.com/jd/d2ac340e728d4c6181e763e772a9944a.jpg
orderItems[1].itemId: 536563
orderItems[1].num: 11
orderItems[1].price: 299000
orderItems[1].totalFee: 3289000
orderItems[1].title: 阿尔卡特 (OT-927) 炭黑 联通3G手机 双卡双待
orderItems[1].picPath: http://image.taotao.com/jd/4ef8861cf6854de9889f3db9b24dc371.jpg
orderItems[2].itemId: 832739
orderItems[2].num: 10
orderItems[2].price: 199000
orderItems[2].totalFee: 1990000
orderItems[2].title: 中兴 U288 珠光白 移动3G手机
orderItems[2].picPath: http://image.taotao.com/jd/4021f8a1ffcc4ae2a313c2012d9f35c8.jpg
payment: 912590.00
orderShipping.receiverName: 陈晨
orderShipping.receiverMobile: 13800807944
orderShipping.receiverState: 北京
orderShipping.receiverCity: 北京
orderShipping.receiverDistrict: 海淀区
orderShipping.receiverAddress: 清华大学
编辑订单order的Controller
业务逻辑层 jt-order
能实现即成功
订单入库
2.5.1 业务说明
当用户点击提交订单时要求实现三张表同时入库业务功能,并且保证orderId的值是一致的.
脚手架
jt-web 消费者 controller层
jt-common 接口
jt-order 提供者
页面实现
完美实现
PS:
buffer是安全的 速度还行
速度慢 最安全
订单查询
自我实现
脚手架
web 消费者
common
接口实现类 service层 jt-order
页面实现
超时订单的处理
超时了就处理掉 常用的就是全这圈着的和一个
编辑配置类
今晚 导到sts的