1. 完成购物车删除操作
1.1 请求url地址
1.2 编辑jt-web CartController
/**
* 删除购物车Controller
* url: http://www.jt.com/cart/delete/1474391990.html
* 返回值: 重定向到购物车列表
*/
@RequestMapping("delete/{itemId}")
public String deleteCarts(Cart cart){
Long userId = UserThreadLocal.get().getId();
cart.setUserId(userId);
cartService.deleteCart(cart);
return "redirect:/cart/show.html";
}
1.3编辑jt-cart DubboCartServiceImpl
@Override
public void deleteCart(Cart cart) {
cartMapper.delete(new QueryWrapper<>(cart));
}
2. 完成用户拦截器操作
2.1 需求说明
如果用户没有登录,则不允许访问购物车/订单等敏感操作.应该重定向到用户登录页面
方法:
- shiro安全框架 只适用于后端程序.
- 拦截器机制
2.2 SpringMVC调用规则
2.3 编辑配置类配置拦截器
//完成拦截器的配置
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(userInterceptor)
.addPathPatterns("/cart/**","/order/**");//拦截方式 /** 表示拦截多级目录
}
2.4 了解ThreadLocal
名称: 本地线程变量
作用: 在同一个线程内,实现数据共享
2.4.1 编辑UserThreadLocal工具API
package com.jt.util;
import com.jt.pojo.User;
public class UserThreadLocal {
private static ThreadLocal<User> userThreadLocal = new ThreadLocal<>();
//使用ThreadLocalAPI存数据
public static void set(User user){
userThreadLocal.set(user);
}
//使用ThreadLocalAPI 取数据
public static User get(){
return userThreadLocal.get();
}
//删除数据
//目的: 防止内存泄漏
public static void remove(){
userThreadLocal.remove();
}
}
2.5 定义拦截器
package com.jt.interceptor;
import com.jt.Util.CookieUtils;
import com.jt.Util.ObjectMapperUtil;
import com.jt.pojo.User;
import com.jt.util.UserThreadLocal;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import redis.clients.jedis.JedisCluster;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
public class UserInterceptor implements HandlerInterceptor {
@Autowired
private JedisCluster redis;
/*返回值说明:
false 表示拦截
true 放行
判断依据: cookie中是否有记录 reids中是否有记录
*/
//处理器执行之前
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String ticket = CookieUtils.getCookieValue(request, "JT_TICKET");
if (StringUtils.hasLength(ticket) && redis.exists(ticket)) {//查看cookie/redis中是否有值
//从redis中获取用户id
String json = redis.get(ticket);
User user = ObjectMapperUtil.toObj(json, User.class);
//2. 利用request对象实现用户id传递到Controller层,常用方式
request.setAttribute("JT_USER", user);
// 3.利用ThrearLocal存取数据
UserThreadLocal.set(user);
return true;//放行
}
//请求如果被拦截,一般都要配合重定向方法使用
response.sendRedirect("/user/login.html");
return false;
}
//处理器执行后
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
//业务调用之前
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
// 1.清空request对象
request.removeAttribute("JT_USER");
// 2.清空ThreadLocal数据
UserThreadLocal.remove();
}
}
3. 小结
3.1 用户登录机制说明
3.1.1 用户登录
3.1.2 用户回显
如果用户登录成功之后,会在cookie中记录TICKET登录凭证.利用跨域机制(JSONP|CORS) 通过TICKET数据信息查询用户数据.之后返回
3.1.3 用户退出
删除TICKET/REDIS中的数据
3.1.4 前端权限机制
通过拦截器实现权限的控制.如果用户不登录,则不允许访问涉密数据.使用的接口HandlerInterceptor 其中有3个方法用来控制程序运行的轨迹. 在拦截器中如果需要实现数据的传递,可以使用ThreadLocal或者Request对象的方式获取.
但是需要注意:数据存储之后记得清空 防止内存泄露.
4. 订单模块实现
4.1 项目创建并添加依赖
<?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">
<parent>
<artifactId>jt</artifactId>
<groupId>com.jt</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jt-order</artifactId>
<!--添加依赖 jt-common-->
<dependencies>
<dependency>
<groupId>com.jt</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>
4.2 表关系设计图
4.3 pojo对象创建以及相关配置
4.4 编辑yml配置文件
server:
port: 8095
servlet:
context-path: /
spring:
datasource:
#如果需要项目发布,则数据库地址必须配置远程数据库
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 #每个服务都应该有自己特定的端口