登陆 | 注册 设为首页 | 加入收藏 | 联系我们
太和养老网
热词老年艺术  助老机构  养老系统  

中心区域北京 天津 河北 山西 内蒙古 辽宁 吉林 黑龙江 上海 江苏 浙江 安徽 福建 江西 山东 河南 湖北 湖南 广东 广西 海南 重庆 四川 贵州 云南 西藏 陕西 甘肃 青海 宁夏 新疆 香港 澳门 台湾 全国城市养老院目录 全国县市养老院汇总目录 太和AI作品展 太和养老艺术网AI作品展示

Redis实战之session共

 

2023/7/11 10:21:45 ('互联网')

当线上集群时候,会出现session共享问题。

虽然Tomcat提供了session copy的功能,但是缺点比较明显:

1:当Tomcat多的时候,session需要大量同步到多台集群上,占用内网宽带

2:同一个用户session,需要在多个Tomcat中都存在,浪费内存空间

如果要替换掉Tomcat的session共享,替代方案应该满足:

1:数据共享

2:内存存储

3:key\value结构

基于Redis实现共享session登录

再来回顾下将验证码保存在session中业务流程

展开全文

我们在session中存放的是:session.setAttribute("code", code); 因为session的特点,每次访问都是一个新的sessionId.我们可以直接使用code作为key.思考:那么如果换成了Redis,还能使用code作为可以吗?

将用户信息存放在session中流程:

用户信息在session中存放:session.setAttribute("user", user); 同样思考:那么如果换成了Redis,还能使用user作为可以吗?

将code和user信息存放在Redis中,流程如下:

验证码数据结构是:string类型的

用户对象数据类型是:hash类型的

根据上面分析,我们修改原来代码:

需要考虑的是:Redis的key规则、过期时间

1:发送验证码的时候,将验证码存放到Redis中时候,需要考虑过期时间。其核心代码如下:

stringRedisTemplate.opsForValue().set(LOGIN_CODE_KEY + phone, code, LOGIN_CODE_TTL, TimeUnit.MINUTES);

2:用户登录的时候,将校验验证码以及用户信息存放到Redis中后,返回token

需要考虑的:

1:token不能重复

2:用户过期时间

3:登录成功后,要将token返回给前端

4:用户只要访问,Redis中的过期时间就要延长-在拦截器中处理的

用户登录核心代码修改:

//2.1:校验验证码是否正确

//String code = (String) session.getAttribute("code");

String code = stringRedisTemplate.opsForValue().get(LOGIN_CODE_KEY + phone);

if (StringUtils.isEmpty(code) || !code.equals(loginForm.getCode())) {

return Result.fail("验证码错误!");

//2.2:根据手机号查询,如果不存在,创建新用户

QueryWrapper<User> queryWrapper = new QueryWrapper<>();

queryWrapper.select("id", "phone", "nick_name");

queryWrapper.eq("phone", phone);

User user = this.getOne(queryWrapper);

if (Objects.isNull(user)) {

log.info("新建用户");

//新建用户

user = createUserWithPhone(phone);

//2.3:保存用户到session中

UserDTO userDTO = new UserDTO();

userDTO.setId(user.getId());

userDTO.setIcon(user.getIcon());

userDTO.setNickName(user.getNickName());

//session.setAttribute("user", userDTO);

//2.3.1:获取随机的token,作为用户登录的令牌

String token = UUID.randomUUID().toString(true);

//2.3.2:将用户以hash类型存放到Redis中==》将user对象转换成map

//user对象里有非string类型的字段,用这个方法会报错的

// Map<String,Object> userMap = BeanUtil.beanToMap(userDTO);

Map<String,Object> userMap = BeanUtil.beanToMap(userDTO,new HashMap<>()

, CopyOptions.create()

.setIgnoreNullValue(true)

.setFieldValueEditor((fieldName,fieldValue)->fieldValue.toString()));

stringRedisTemplate.opsForHash().putAll(LOGIN_USER_TOKEN_KEY+token,userMap);

//LOGIN_USER_TOKEN_TTL

stringRedisTemplate.expire(LOGIN_USER_TOKEN_KEY+token,LOGIN_USER_TOKEN_TTL,TimeUnit.MINUTES);

//2.3.3: 将token返回

return Result.ok(token);

需要注意:

在使用stringRedisTemplate存放hash对象的时候,对象中所有的key只能是string类型,如果存在非string类型会报错的。所以这里使用了hootool的BeanUtil工具类:

Map<String,Object> userMap = BeanUtil.beanToMap(userDTO,new HashMap<>()

, CopyOptions.create()

.setIgnoreNullValue(true)

.setFieldValueEditor((fieldName,fieldValue)->fieldValue.toString()));

拦截器修改代码:

因为拦截器是我们自定义的,所以不能被spring容器管理的,RedisTemplate就不能自动注入了。我们就使用有参构造器,传递:

public class LoginRedisInterceptor implements HandlerInterceptor {

private StringRedisTemplate stringRedisTemplate;

* 因为这个类不能被spring管理,所以不能直接注入RedisTemplate对象。通过构造函数传递

* @param stringRedisTemplate

public LoginRedisInterceptor(StringRedisTemplate stringRedisTemplate){

this.stringRedisTemplate = stringRedisTemplate;

@Override

public boolean preHandle( {

//1:从请求中获取到token

String token = request.getHeader("authorization");

if(StringUtils.isEmpty(token)){

response.setStatus(401);

return false;

//2:基于token获取redis中用户对象

String key = LOGIN_USER_TOKEN_KEY+token;

Map<Object,Object> userMap = stringRedisTemplate.opsForHash().entries(key);

//3:判断

if(userMap.isEmpty()){

resp



扫码加微信详细咨询太和智慧养老产品和平台服务!

 

 





版权声明:

---------------------------------------------------------------


所有信息来源于互联网,本文的版权归原作者所有,不代表本网观点和立场。

本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请发送邮件至 81480447@qq.com 举报,一经查实,本站将立刻删除。



扫码加微信详细咨询太和智慧养老产品和平台服务!

 

养老资讯
助老机构介绍
评论
已有 0 条评论

最新评论

推荐养老院

您希望养老院位于
  • 不限
  • 东城
  • 西城
  • 崇文
  • 宣武
  • 朝阳
  • 丰台
  • 石景山
  • 海淀
  • 门头沟
  • 房山
  • 通州
  • 顺义
  • 昌平
  • 大兴
  • 怀柔
  • 平谷
  • 延庆
  • 密云
您希望的价格范围
  • 不限
  • 500以下
  • 500-1000
  • 1000-2000
  • 2000-3000
  • 3000-5000
  • 5000以上
老人的情况是
  • 不限
  • 自理
  • 半自理
  • 全护理
  • 特护

姓名

年龄

电话

全国城市养老院



关于我们 | 联系方式 | 网站地图 | 友情链接

Copyright 2010-2022 京ICP备18035644号-3 北京太和 版权所有