注册模块:
注册使用手机号发送验证码注册的方式,使用的是阿里云的短信发送服务,然后进行认证,有个60s的时间,可以存到redis中,key是手机号,value是验证码。
使用Spring自带的BCryptPasswordEncoder,每次加密得到的密文都不一样。在登陆的时候,可以用matches方法,一个参数是明文,一个参数是数据库存的密文,查看是否匹配到,返回一个boolean类型。
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
//$2a$10$GT0TjB5YK5Vx77Y.2N7hkuYZtYAjZjMlE6NWGE2Aar/7pk/Rmhf8S
//$2a$10$cR3lis5HQQsQSSh8/c3L3ujIILXkVYmlw28vLA39xz4mHDN/NBVUi
String encode = bCryptPasswordEncoder.encode("123456");
boolean matches = bCryptPasswordEncoder.matches("123456", "$2a$10$GT0TjB5YK5Vx77Y.2N7hkuYZtYAjZjMlE6NWGE2Aar/7pk/Rmhf8S");
System.out.println(encode+"==>" + matches);
登录模块:
根据输入的手机号或者用户名去数据库查询,如果未查到,则登陆失败,没有用户名,提示去注册;如果查到了,则获取到数据库的密码,和页面传过来的密码进行match,如果匹配成功,则登录,如果不成功,则提示账户密码错误。
如果成功,回到首页,则应该具备了用户的信息。单体应用,我们可以直接获取session,
在分布式环境下,使用springsession解决session共享问题,将session存储在redis中,配置sessionconfig,
auth2 完成子域session共享,扩大作用域,序列化方式,创建配置类
@Configuration
public class GulimallSessionConfig {
@Bean
public CookieSerializer cookieSerializer() {
DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
//放大作用域
cookieSerializer.setDomainName("gulimall.com");
cookieSerializer.setCookieName("GULISESSION");
return cookieSerializer;
}
@Bean
public RedisSerializer<Object> springSessionDefaultRedisSerializer() {
return new GenericJackson2JsonRedisSerializer();
}
}
多个系统时,单点登录,由于当时时间紧迫,这个了解了一下,并没有进行实践。
购物车模块:
购物车在redis中存储类型:
购物车里面有多个购物项,因为购物车的数据要频繁修改(数量等),因此用hash这个数据类型
不同用户应该有独立的购物车,因此购物车应该以用户的作为 key 来存储
综上所述,我们的购物车结构是一个双层 Map:Map> - 第一层 Map,Key 是用户 id - 第二层 Map,Key 是购物车中商品 id,值是购物项数据
操作购物车:
1、首先获取需要操作的购物车
boundHashOps(“key”),根据这个key都多种操作。
/**
* 获取到我们要操作的购物车
* @return
*/
private BoundHashOperations<String, Object, Object> getCartOps() {
//先得到当前用户信息
UserInfoTo userInfoTo = CartInterceptor.toThreadLocal.get();
String cartKey = "";
if (userInfoTo.getUserId() != null) {
//gulimall:cart:1
cartKey = CART_PREFIX + userInfoTo.getUserId();
} else {
cartKey = CART_PREFIX + userInfoTo.getUserKey();
}
//绑定指定的key操作Redis,进行增删改查
BoundHashOperations<String, Object, Object> operations = redisTemplate.boundHashOps(cartKey);
return operations;
}
2、远程调用product查询商品信息
1、查询到需要添加的商品信息,
2、查询到远程sku的组合信息,
线程池异步,CompletableFuture异步实现1 2
要等待两个都完成,再进行后续的操作。
3、添加到购物车(redis)
value是json字符串的格式,先将其转化问json字符串,拿出来的时候也要转化为对象。还有先进行判断,购物车是否有该商品,如果没有,则按上述步骤添加新信息,如果有,则去除购物项信息,数量+1,再存入。
//判断Redis是否有该商品的信息
String productRedisValue = (String) cartOps.get(skuId.toString());
//如果没有就添加数据
if (StringUtils.isEmpty(productRedisValue)) {
}
//等待所有的异步任务全部完成
CompletableFuture.allOf(getSkuInfoFuture, getSkuAttrValuesFuture).get();
String cartItemJson = JSON.toJSONString(cartItemVo);
cartOps.put(skuId.toString(), cartItemJson);