springboot+shiro+redis实现分布式项目共享session

 

默认使用开源库org.crazycake:shiro-redis:2.4.2.1集成redis,直接使用

   


		
			org.crazycake
			shiro-redis
			2.4.2.1-RELEASE
		

引入依赖之后直接配置

详情可以参考博客

https://blog.csdn.net/rexueqingchun/article/details/92651369?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-2&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-2

配置ShiroConfiguration.java,主要配置redis和session

    //权限管理,配置主要是Realm的管理认证
    @Bean
    public SecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(myShiroRealm());
        securityManager.setSessionManager(sessionManager());
        //配置自定义缓存redis
       securityManager.setCacheManager(cacheManager());
        return securityManager;
    }  
//session管理
    @Bean
    public SessionManager sessionManager() {
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
        Collection listeners = new ArrayList();
        listeners.add(new MySessionListener());
        sessionManager.setSessionListeners(listeners);
        //设置session超时时间为1小时(单位毫秒)
        //sessionManager.setGlobalSessionTimeout(3600000);
        sessionManager.setGlobalSessionTimeout(-1);//永不超时
        //设置redisSessionDao
        sessionManager.setSessionDAO(redisSessionDAO());
        return sessionManager;
    }

    //配置cacheManager
    public RedisCacheManager cacheManager() {
        RedisCacheManager redisCacheManager = new RedisCacheManager();
        redisCacheManager.setRedisManager(redisManager());
        return redisCacheManager;
    }

    //配置redisManager
    public RedisManager redisManager() {
        RedisManager redisManager = new RedisManager();
        redisManager.setHost(host);
        redisManager.setPort(port);
        redisManager.setTimeout(timeout);
//        redisManager.setPassword(password);
        redisManager.setExpire(3600);//配置缓存过期时间(秒)
        return redisManager;
    }

    //配置redisSessionDAO
    @Bean
    public RedisSessionDAO redisSessionDAO() {
        RedisSessionDAO redisSessionDAO = new RedisSessionDAO();
        redisSessionDAO.setRedisManager(redisManager());
        return redisSessionDAO;
    }

启动项目

http://localhost:8888/site/login;JSESSIONID=18c3ae74-9475-4fb5-86ea-3bed48ed5c9b

JSESSIONID作为存储redis的key值,session就是val,JSESSIONID的key值是通过RedisSessionDao里的

doCreate方法获取的UUID,打开登录界面可以看看redis数据库里有没有数据

springboot+shiro+redis实现分布式项目共享session_第1张图片

如果key值和登录的JSESSIONID的值一致的话,说明存储正确。

具体怎么实现可以看一下crazycake提供的源码,很有帮助,当时因为user实体类序列化之后,登录时报错ClassCastException,

具体原因引用网上广为流传的一个解释

大家都知道虚拟机的默认类加载机制是通过双亲委派实现的。springboot为了实现程序动态性(比如:代码热替换、模块热部署等,白话讲就是类文件修改后容器不重启),“破坏或牺牲” 了双亲委派模型。springboot通过强行干预-- “截获”了用户自定义类的加载(由jvm的加载器AppClassLoader变为springboot自定义的加载器RestartClassLoader,一旦发现类路径下有文件的修改,springboot中的spring-boot-devtools模块会立马丢弃原来的类文件及类加载器,重新生成新的类加载器来加载新的类文件,从而实现热部署。比较流行的OSGI也能实现热部署)。

这里大致意思差不多就是shiro-redis使用的类加载器和其他类使用的类加载器不同

解决问题有这么几种方式

 1.删掉pom下的热部署(我觉得这个方法不是很好)

 2.最直接的就是让所有的类的类加载器是同一个。 要实现这个,需要生成一个文件resources/META-INF/spring-devtools.properties,然后修改热部署配置:

restart.include.shiro-redis=/shiro-[\\w-\\.]+jar

第二种方法具体参考  https://blog.csdn.net/feinifi/article/details/85237166

 

 

如不能反序列化,查看依赖是否添加 该依赖


   org.apache.shiro
   shiro-spring
   1.4.0

你可能感兴趣的:(springboot,shiro)