我们要写什么呢,我们要在服务端写一个cookie,而这个cookie呢,是写在客户端上的,那他写的就是登陆时候的,sessionId,非常简单,我们开始写一下,首先新建一个类,我们就在util里面创建,这个类呢,就叫CookieUtil,首先声明两个String类型的常量,这是final的,COOKIE_DOMAIN,先写一个空字符串放着,然后我们再写一个,COOKIE_NAME,cookie的名字,这些名字是我们服务端要送到,客户端浏览器上的,这个名字我们就叫mmall_login_cookie,其实这里要说一下,我们写在happymall,这个domain下面之后呢,那user.happymall,还有www.happymall,还有后续订单服务化之后,order.mall,这里面的cookie都是可以看到的,也就是把我们的cookie,写在一个domain,大一点的domain,写在一级域名下的,那我们也可以写在二级域名下,例如我们写在abc.happymall.com,这么一个二级域名下,三级域名比如3.abc.happymall.com,能够读到abc.happymall的cookie,那kk.happymall和abc并行的域名,它是读不到abc.happymall.com下的cookie的,我们先写在一级域名下,那很简单,我们现在封装一个方法,那我们写cookie的时候,肯定要放到response里边,我们把HttpServetResponse拿过来,response,第二个就是写我们的value,那我们称之为token,也就是JSESSIONID,那怎么写呢,在new Cookie的时候,要写他的name和value,name就是cookie_name,那他的value就是token,很简单的一个构造器,然后我们set他的domain,上面声明了这个常量,我们还要set他的path,然后我们还要设置一个maxage,这个是什么呢,cookie的有效期,如果我们写-1的话,就代表永久的,那这个单位是秒,这里面还有一个注释,如果这个maxage不设置的话,那cookie就不会写入硬盘,而是写在内存,只在当前页面有效,也就是我们设置这个之后,才会存在硬盘当中,包括我们关闭浏览器等等,重启电脑cookie都存在,那因为它是秒,我们设置他的有效期为一年,60这是一分钟,60秒就是一分钟,现在再乘以60代表1小时,然后24代表一天,乘以365,这个就设置一年的有效期,就用我们前面讲的slfj,log.info,write cookiename,占位,write cookievalue,占位,后面写上直接冲ck里面读,那这个path也说一下,这个设置代表在根目录,直接斜杠,如果我设置一个path为test,那么就是说只有test目录下,或者test子目录页面,才能获取到这个cookie,那我们就把它放到根目录下,然后response.addCookie,把这个ck放进来,写入cookie,那么一口气封装完,再写一个读取cookie,那我们在登陆的时候,写入了cookie,写入了mmall_login_cookie,那我们在获取user的时候,我们就要读取这个cookie,拿到当时登陆时候,存的JSESSIONID,这个就是一个string了,因为要读,readLoginToken
 private final static String COOKIE_DOMAIN = ".happymmall.com";private final static String COOKIE_NAME = "mmall_login_token";public static void writeLoginToken(HttpServletResponse response,String token){Cookie ck = new Cookie(COOKIE_NAME,token);ck.setDomain(COOKIE_DOMAIN);ck.setPath("/");//代表设置在根目录ck.setHttpOnly(true);//单位是秒。//如果这个maxage不设置的话,cookie就不会写入硬盘,而是写在内存。只在当前页面有效。ck.setMaxAge(60 * 60 * 24 * 365);//如果是-1,代表永久log.info("write cookieName:{},cookieValue:{}",ck.getName(),ck.getValue());response.addCookie(ck);}
我们肯定是从request里面拿,request.getCookies,它是一个返回cookie数组的方法,这里有一个判断,如果不为空的话就给他做一个遍历,做each遍历,然后打印他的cookie,我们读取到之后要做一个判断了,这里说一下StringUtils的这个equal方法,里面做了空判断,比较好用一些
    /*** <p>Compares two Strings, returning <code>true</code> if they are equal.</p>** <p><code>null</code>s are handled without exceptions. Two <code>null</code>* references are considered to be equal. The comparison is case sensitive.</p>** <pre>* StringUtils.equals(null, null)   = true* StringUtils.equals(null, "abc")  = false* StringUtils.equals("abc", null)  = false* StringUtils.equals("abc", "abc") = true* StringUtils.equals("abc", "ABC") = false* </pre>** @see java.lang.String#equals(Object)* @param str1  the first String, may be null* @param str2  the second String, may be null* @return <code>true</code> if the Strings are equal, case sensitive, or*  both <code>null</code>*/public static boolean equals(String str1, String str2) {return str1 == null ? str2 == null : str1.equals(str2);}
这个方法已经封装好了,并不会包空指针异常,就是没有读到我们想要的login cookie,那这个方法就实现了
    public static String readLoginToken(HttpServletRequest request){Cookie[] cks = request.getCookies();if(cks != null){for(Cookie ck : cks){log.info("read cookieName:{},cookieValue:{}",ck.getName(),ck.getValue());if(StringUtils.equals(ck.getName(),COOKIE_NAME)){log.info("return cookieName:{},cookieValue:{}",ck.getName(),ck.getValue());return ck.getValue();}}}return null;}
注销登录就要把这个cookie删除,同样的他不需要返回值,delLoginToken,删除我既要读,也要写,那这里面就要讲一下,怎么删除cookie,那把request和response都拿过来,读从request里面读,写从response里面写,Cookie数组,如果不等于空,遍历它,重要的在这里,如果我们把maxage设置为0的话,代表删除此cookie,那删除就通过把有效期设置成0,就代表删除了这个cookie,然后打个log,然后response.addCookie,也就是我们add一个有效期为0的cookie,放到response里边,然后返回给浏览器,浏览器就会把这个cookie删除掉,有效期是0,直接结束这个方法,不再执行循环,那现在我们看一下
    public static void delLoginToken(HttpServletRequest request,HttpServletResponse response){Cookie[] cks = request.getCookies();if(cks != null){for(Cookie ck : cks){if(StringUtils.equals(ck.getName(),COOKIE_NAME)){ck.setDomain(COOKIE_DOMAIN);ck.setPath("/");ck.setMaxAge(0);//设置成0,代表删除此cookie。log.info("del cookieName:{},cookieValue:{}",ck.getName(),ck.getValue());response.addCookie(ck);return;}}}}
读删除都写完了,那我们debug来测试一下,还是来到UserController里面,我们在这里面直接调用,把response传进去,所以在我们login参数里面,就要加response,然后response放到这里面,那么value就是session的id,为了调试,一起领着大家一起看,现在我们调用一下读取readCookie,把request放到里边,直接进行一个测试,然后我们还要删除掉他,删除它我们直接调用,把request和response都放到这里,实际上我们只要调用write就可以了,加到这里是为了一起测试,因为我们还有一个tomcat2
    /*** 用户登录* @param username* @param password* @param session* @return*/@RequestMapping(value = "login.do",method = RequestMethod.POST)@ResponseBodypublic ServerResponse<User> login(String username, String password, HttpSession session, HttpServletResponse httpServletResponse){ServerResponse<User> response = iUserService.login(username,password);if(response.isSuccess()){//            session.setAttribute(Const.CURRENT_USER,response.getData());CookieUtil.writeLoginToken(httpServletResponse,session.getId());RedisShardedPoolUtil.setEx(session.getId(), JsonUtil.obj2String(response.getData()),Const.RedisCacheExtime.REDIS_SESSION_EXTIME);}return response;}@RequestMapping(value = "logout.do",method = RequestMethod.POST)@ResponseBodypublic ServerResponse<String> logout(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse){String loginToken = CookieUtil.readLoginToken(httpServletRequest);CookieUtil.delLoginToken(httpServletRequest,httpServletResponse);RedisShardedPoolUtil.del(loginToken);//        session.removeAttribute(Const.CURRENT_USER);return ServerResponse.createBySuccess();}

单点登录Redis存储Session及SessionId问题说明与集群实战-2相关推荐

  1. 单点登录Redis存储Session及SessionId问题说明与集群实战-1

    断点已经到这儿了,sessionId我们看一下,sessionId是B218,我们把value copy一下 放到这里,然后让Redis存上,key就是session的id,value就是user,后 ...

  2. 单点登录Redis存储Session及SessionId问题说明与集群实战-3

    那现在我们就是要把sessionID的login请求,我们再看一下redis,回到我们的代码,我们现在不请求localhost:8080了,我们要请求happymall.com,因为我们 已经把他配置 ...

  3. 单点登录Redis存储Session及SessionId问题说明与集群实战-4

    现在就是要改造我们getUserInfo,因为我们不会再从session里面获取用户,首先我们要哪一个login_token,这个时候拿到loginToken,如果loginToken是empty的话 ...

  4. 单点登录Redis存储Session及Cookie场景介绍

    首先response如果是成功的话,就是登陆成功,我就不往session里面放值了,直接调用RedisPoolUtil,setEx方法,在设置的时候,直接把他的时间加上,key就用session.ge ...

  5. yii2设置session时间_关于 Swoft 2.0 版本用 Redis 存储 session 时配置问题

    Swoft 2.0 在 session 配置上和 1.0 还是有一些不同地方,而关于这些在 github 上完全没有任何说明,甚至连文档也没有.经过逐步梳理源代码(其中要理解他的 "注解&q ...

  6. 使用Redis缓存Shiro授权认证信息,搭建集群权限系统

    应用如果做负载均衡,集群间session需要共享,如果session没有共享,用户登录系统以后session保存在登录的应用里面,其他应用里面没有session,没有登陆状态,访问会失败.下面介绍一个 ...

  7. redis的三大模式主从,哨兵和集群

    一.前言 二.redis主从复制 1.主从复制的作用: 2.主从复制的流程 3.搭建主从复制 3.1.搭建环境 3.2.安装redis 3.3.主服务器配置查看以下行 3.4.从服务器配置查看以下行 ...

  8. Redis高可用——主从复制、哨兵模式、集群

    文章目录 一.Redis高可用 1.什么是高可用 2.Redis的高可用技术 二.Redis主从复制 1.Redis主从复制的作用 2.主从复制的流程 三.主从复制的搭建 实验准备 1.所有主机安装R ...

  9. Redis实践(二)高可用的集群+哨兵部署

    项目中通常会需要若干台Redis服务器来协同担当起内存数据库的工作,在redis的部署方案上要考虑下面几点: 结构上,单个 Redis 服务器会发生单点故障,而且一台服务器需要承受所有的请求负载. 这 ...

最新文章

  1. 解决会声会影x7 x8打开即“已停止工作问题”
  2. 散列表查找的一个实例
  3. MyBatis动态SQL底层原理分析
  4. WCF技术剖析之十一:异步操作在WCF中的应用(上篇)
  5. 【vue】vue.config.js
  6. JavaScript 中的this的简便判断
  7. LeetCode 2039. 网络空闲的时刻(BFS)
  8. mysqli与pdo防sql注入源码
  9. linux windows文件 编码_Mac, Windows和Linux电脑之间如何快速传输文件
  10. OpenCV精进之路(零):core组件——Mat和IplImage访问像素的方法总结
  11. 东北大学金工实习工程实训习题
  12. gmail邮箱注册_Android中的Google帐户集成–使用Gmail登录
  13. cgi进程设置多少 宝塔_【存档】新手宝塔建站详细步骤
  14. Android下载多张图片保存到本地
  15. SQL Server 2008 R2 安装 (转)
  16. 3d建模师就业前景?
  17. python给图片加半透明水印_图片添加半透明文字水印 Python
  18. 淘宝拍立淘iOS相册架构设计小结
  19. 【论文笔记】A Multi-Task Learning Formulation for Predicting Disease Progression
  20. npm包管理的一个小错误, No repository field,No description

热门文章

  1. 查询数据库中所有表的行数(sqlserver 2000)
  2. i2c--ioctl--主机控制器驱动(i2c_adapter)--外设驱动(i2c_driver)
  3. 收集下关系数据库处理亿万级别的数据
  4. 【Hibernate】Hibernate实体关系映射——双边的一对一关系
  5. 分页控件 实战 Post篇
  6. Java基本类型与运算
  7. 2018--Linux命令总结整理复习版
  8. 绕月飞行维生系统进展如何?美国人准备好了吗
  9. 【Adaboost算法】C++转C, 分类器结构设计
  10. ·XP注册表修改大全