基于Cookie+Redis+Filter实现session共享

news/2024/5/18 15:45:54 标签: session, cookie, redis, 缓存

基于Cookie+Redis+Filter实现session共享

  • 未登录
  • 登录实现
  • 登录情况下获取用户信息
  • 重置Session过期时间
  • 退出销毁session

未登录

封装Cookie工具类
在这里插入图片描述

登录实现

将Session Id和用户信息存储到Redis中,并添加一个Cookie。
@WebServlet("/login")
public class Login extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doGet(req,resp);
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

            HttpSession session = req.getSession();
            String sessionId = session.getId();

            //设置cookie的名称
            Cookie cookie = new Cookie("sso-cookies",sessionId);
            //子域名可以共享一级域名的cookie
            cookie.setDomain("localhost");
            //设置cookie的访问仅通过http方式,在一定程度上防止脚本攻击
            cookie.setHttpOnly(true);
            //如果不设置该值,则cookie不会保存到硬盘中,只存在于内存中,只在当前页面有效。
            //单位为s,如果设置为-1,则代表永久
            cookie.setMaxAge(60*30);
            //子级目录可以共享根目录下的cookie
            cookie.setPath("/");
            resp.addCookie(cookie);

            //序列化用户信息
            JSONObject user = new JSONObject();
            user.put("name","张三");
            user.put("pwd",123);

            //将sessionId与用户信息保存到Redis中
            Jedis jedis = new Jedis();
            jedis.setex(sessionId,60*30,user.toJSONString());
            
            req.getRequestDispatcher("loginSuccess.jsp").forward(req, resp);
    }
}
登录成功后两个tomcat均有一个相同的cookie

在这里插入图片描述

查看redissession过期时间 

在这里插入图片描述

查看redis中存储的用户信息

在这里插入图片描述

登录情况下获取用户信息

@WebServlet("/getUser")
public class getUser extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取cookies
        Cookie[] cookies = req.getCookies();
        Map<String,Cookie> cookieMap = new HashMap<String,Cookie>();
        if (cookies != null){
            for (Cookie cookie: cookies) {
                cookieMap.put(cookie.getName(),cookie);
            }
        }
        
        Cookie cookie = cookieMap.get("sso-cookies");
       if(StringUtils.isNotBlank(cookie )){
	        String  value= cookie.getValue();
	        Jedis jedis = new Jedis();
	        if (StringUtils.isNotBlank(value) && StringUtils.isNotBlank(jedis.get(value))){
	            JSONObject jsonObject = JSONObject.parseObject(jedis.get(value));
	            jsonObject.put("Tomcat1","Tomcat1");
	            resp.getWriter().println(jsonObject.toString());
        }
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doGet(req, resp);
    }
}

此时不论从哪个服务器中都能取出用户信息


在这里插入图片描述

重置Session过期时间

由于会话session是有过期时间,在一定时间内若不进行任何操作,session便过期,此时再将进行操作将要求重新登录.所有需要对session过期时间进行重置处理

@WebServlet("/rest.do")
public class ResetSession extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf-8");
        resp.getWriter().println("重置session过期时间!");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doGet(req, resp);
    }
}

自定义过滤器处理相应业务
public class SessionExtendFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //将ServletRequest转换为HttpServletRequest
        HttpServletRequest request = (HttpServletRequest)servletRequest;
        Cookie[] cookies = request.getCookies();
        Map<String,Cookie> cookieMap = new HashMap<String,Cookie>();
        if (cookies != null){
            for (Cookie cookie: cookies) {
                cookieMap.put(cookie.getName(),cookie);
            }
        }
        String value=null;
        if (cookieMap.containsKey("sso-cookies")){
            Cookie cookie = cookieMap.get("sso-cookies");
            value= cookie.getValue();
        }
        //如果token不为空的话,符合条件,则获取user信息,user不为空,则将redis缓存中的session时间重置为指定时时长
        if(StringUtils.isNotBlank(value)){
            String userstr = RedisUtil.get(value);
            Object user = JSONObject.parse(userstr);
            if( user!= null){
                //如果user不为空,则重置session的时间,即调用expire命令
                RedisUtil.expire(value, 60*30);
            }
        }
        filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override
    public void destroy() {

    }
}
web.xml配置过滤器
<web-app>
  <filter>
    <filter-name>sessionExtendFilter</filter-name>
    <filter-class>cn.ybzy.demo.SessionExtendFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>sessionExtendFilter</filter-name>
    <url-pattern>*.do</url-pattern>
  </filter-mapping>
</web-app>
执行过滤器方法及验证

在这里插入图片描述
在这里插入图片描述

session_176">退出销毁session

@WebServlet("/loginout")
public class LoginOut extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Cookie[] cookies = req.getCookies();
        Map<String,Cookie> cookieMap = new HashMap<String,Cookie>();
        if (cookies != null){
            for (Cookie cookie: cookies) {
                cookieMap.put(cookie.getName(),cookie);
            }
        }

        Cookie cookie = cookieMap.get("sso-cookies");

       if(StringUtils.isNotBlank(cookie )){
        //删除redis中存储session
        Jedis jedis = new Jedis();
        jedis.del(cookie.getValue());

        //删除cookie
        cookie.setDomain("localhost");
        cookie.setPath("/");
        //设置成0,代表删除此cookie
        cookie.setMaxAge(0);
        resp.addCookie(cookie);
        req.getRequestDispatcher("index.jsp").forward(req, resp);
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doGet(req, resp);
    }
}
执行退出及查看

在这里插入图片描述
在这里插入图片描述


http://www.niftyadmin.cn/n/876825.html

相关文章

基于Nginx的负载均衡,使用Docker搭建Tomcat集群

基于Nginx的负载均衡&#xff0c;使用Docker搭建Tomcat集群Tomcat单机与集群Nginx负载均衡NginxTomcat搭建集群Session不共享问题Session共享解决方案Tomcat单机与集群 单机(同个session) #mermaid-svg-1Xz4gLXVvFxf2G8V {font-family:"trebuchet ms",verdana,arial…

基于Docker安装部署Minion对象存储服务

基于Docker安装部署Minion对象存储服务Minion(帮助文档)是一款基于Go语言的高性能对象存储服务&#xff0c;非常适合于存储大容量非结构化的数据&#xff0c;例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等。 1.拉去鏡像 docker pull minio/minio2.创建容器 docker…

基于spring session实现session共享

1.引入jar包 <dependency><groupId>org.springframework.session</groupId><artifactId>spring-session-data-redis</artifactId><version>x.x.x</version> </dependency>2.配置web.xml <filter><filter-name>sp…

Spring MVC之拦截器的实现与非法请求拦截处理的实现

Spring MVC之拦截器的实现与非法请求拦截处理的实现一、Spring MVC拦截器两种定义方式拦截器interceptor和filter的区别二、拦截器的配置1.实现HandlerInterceptor 接口1.HandlerInterceptor接口方法2.自定义拦截器实现HandlerInterceptor 接口3.配置spring mvc文件4.编写登录方…

Java常用数据类型

数据类型存储大小取值范围默认值byte8位&#xff0c;有符号位-2^7, 2^7-10short16位&#xff0c;有符号位-2^15, 2^15-10int32位&#xff0c;有符号位-2^31, 2^31-10long64位&#xff0c;有符号位-2^63, 2^63-10Lfloat32位 float flt1 6.6F; 0.0double64位 double flt2 6.6…

Spring MVC之全局异常统一处理

Spring MVC之全局异常统一处理一、SpringMVC异常处理1.SpringMVC全局异常流程图2.三种异常处理方式3.未捕获异常的处理二、全局异常统一处理1、添加依赖2、配置异常处理器3、配置Spring Mvc以Json格式输出内容4 、实现HandlerExceptionResolver接口的resolveException方法5、验…

Shiro之与SpringBoot整合

Shiro之与SpringBoot整合一、Shiro与SpringBoot整合1.添加环境依赖2.自定义realm3.编写登录方法4.Shiro配置5.权限相关注解6.Shiro授权7.自定义权限异常处理器二、Shiro之编码加密1.添加密码凭证匹配器2.注册给Realm3.注册时对密码加密4.自定义Realm认证方法作以下处理5.登录调…

Apache Shiro快速入门教程之初识Shiro(一)

Apache Shiro快速入门教程之初识Shiro&#xff08;一&#xff09;Shiro简介1.什么是Shiro?2.Shiro的功能模块3.Shiro的外部结构4.Shiro的内部结构添加依赖环境方式一方式二Shiro认证一、初始化配置文件二、Shiro认证测试Shiro授权一、初始化配置文件二、Shiro授权测试自定义Re…