美文网首页
项目中缓存失效原理

项目中缓存失效原理

作者: 墨色尘埃 | 来源:发表于2018-06-01 17:01 被阅读69次

    首先在登陆页面的时候,会发送验证码请求("http://127.0.0.1:10003/security/vcode?sysCode=102001"),在请求验证码后台接口里通过HttpServletRequest获取到前端传过来的信息。通过HttpSession session = request.getSession()获得session,并将验证码信息存入到session里了,如下代码:

    session.removeAttribute("vcode" + sysCode);
    session.setAttribute("vcode" + sysCode, verifyCode.toLowerCase());
    

    第一次访问时,服务器会创建一个新的sesion,并且把session的Id以cookie的形式发送给客户端浏览器,我猜想request.getSession()方法内部新创建了Session之后一定是做了如下的处理:

     //获取session的Id
     String sessionId = session.getId();
     //将session的Id存储到名字为JSESSIONID的cookie中
     Cookie cookie = new Cookie("JSESSIONID", sessionId);
     //设置cookie的有效路径
     cookie.setPath(request.getContextPath());
     response.addCookie(cookie);
    

    注:通过HttpServletRequest还可以获得前端请求头里的信息

     Enumeration<String> headerNames = request.getHeaderNames();
     Cookie[] cookies = request.getCookies();
     String contentType = request.getContentType();
    

    后台验证码接口:

        /**
         * 获取验证码接口
         * @param request
         * @param response
         * @param sysCode 系统sysCode
         * @throws Exception
         */
        @RequestMapping(value = "/vcode", method = RequestMethod.GET)
        public void getVCode(HttpServletRequest request, HttpServletResponse response, @RequestParam String sysCode) throws
                Exception {
    
            try {
                if (SecurityContextHolder.getContext().getAuthentication().isAuthenticated()
                        && !(SecurityContextHolder.getContext().getAuthentication() instanceof
                        AnonymousAuthenticationToken))
                    request.logout();
            } catch (Exception ex) {
    
            }
    
            HttpSession session = request.getSession();
    
            response.setHeader("Pragma", "No-cache");
            response.setHeader("Cache-Control", "no-cache");
            response.setDateHeader("Expires", 0);
            response.setContentType("image/jpeg");
            String verifyCode = VCodeUtil.generateVerifyCode(4);
    
            log.debug(request.getRemoteAddr() + "获取验证码" + verifyCode);
    
            Enumeration<String> headerNames = request.getHeaderNames();
            Cookie[] cookies = request.getCookies();
            String contentType = request.getContentType();
    
            session.removeAttribute("vcode" + sysCode);
            session.setAttribute("vcode" + sysCode, verifyCode.toLowerCase());
            int w = 100, h = 30;
            VCodeUtil.outputImage(w, h, response.getOutputStream(), verifyCode);
        }
    

    springboot中关于共享session的配置见类HttpSessionConfig
    因为项目使用了共享缓存,所以在登陆成功的时候,会将session通过redis存入内存,用RedisDesktopManager打开

    image.png
    服务器创建session出来后,会把session的id号,以cookie的形式回写给客户机,这样,只要客户机的浏览器不关,再去访问服务器时,都会带着session的id号去,服务器发现客户机浏览器带session id过来了,就会使用内存中与之对应的session为之服务。
    因为session设置了缓存失效时间,所以当RedisDesktopManager打开后里的session失效了就意味着sessionId也失效了,前端发起请求的时候再用cookie来访问,但是cookie里的sessionId已经失效了,所以就会失败,目前做了一个处理就是如果缓存失效就直接跳转到登陆页。

    当需要在程序中手动设置Session失效时,可以手工调用session.invalidate方法,摧毁session。

     HttpSession session = request.getSession();
     //手工调用session.invalidate方法,摧毁session
     session.invalidate();
    

    链接:
    Session和Cookie的主要区别
    共享Session-spring-session-data-redis
    【Spring】Redis的两个典型应用场景

    相关文章

      网友评论

          本文标题:项目中缓存失效原理

          本文链接:https://www.haomeiwen.com/subject/svxhjftx.html