tianyu4552的gravatar头像
tianyu4552 2018-02-28 22:36:07
apache shiro框架内用Redis实现Session共享

通过自定义RedisSessionDao并继承EnterpriseCacheSessionDAO,重写CRUD四个接口,可以实现本地缓存session,并且利用reids在分布式系统下共享session。

EnterpriseCacheSessionDAO实现了shiro框架顶层的SessionDAO接口。

apache shiro框架内用Redis实现Session共享

接口CRUD的详细过程:

1、 创建

protected Serializable doCreate(Session session) {
        // 创建一个Id并设置给Session
        Serializable sessionId = this.generateSessionId(session);
        assignSessionId(session, sessionId);

        // 在 Redis中创建session,并设置过期时间 
        String key = SerializationUtils.sessionKey(sessionId);
        String value = SerializationUtils.sessionToString(session);
        redisManager.setex(key, value, liveSeconds);

        return sessionId;
    }

2、 读取

   @Override
    public Session readSession(Serializable sessionId) throws UnknownSessionException {
        Session s = getCachedSession(sessionId);
         // 如果本地缓存没有,则从 Redis 读取。
        if (s == null || (
                s.getAttribute(AUTHENTICATED_SESSION_KEY) != null
                        && !(Boolean) s.getAttribute(AUTHENTICATED_SESSION_KEY)
        )) {
            s = doReadSession(sessionId);
            if (s == null) {
                throw new UnknownSessionException();
            }
            return s;
        }

        return s;
    }

    /**
     * 从 Redis 上读取 session,并缓存到本地 Cache.
     */
    @Override
    protected Session doReadSession(Serializable sessionId) {
       String value = redisManager.get(SerializationUtils.sessionKey(sessionId));

        // 例如 Redis 调用 flushdb 清空了所有的数据,读到的 session 就是空的
        if (value != null) {
            Session session = SerializationUtils.stringToSession(value);
            super.cache(session, session.getId());

            return session;
        }

        return null;
    }

 

3、更新

     protected void doUpdate(Session session) {
        // 如果会话过期/停止,没必要再更新了
        if (session instanceof ValidatingSession && !((ValidatingSession) session).isValid()) {        
            return;
        }

        String key = SerializationUtils.sessionKey(session.getId());
        String value = SerializationUtils.sessionToString(session);
        redisManager.setex(key, value, liveSeconds);
    }

 

4、删除

    protected void doDelete(Session session) {

        redisManager.del(SerializationUtils.sessionKey(session.getId()));

        // 发布消息通知其它 Server 上的 cache 删除 session.
        redisManager.publish("session:clear", session.getId() + "");
    }

打赏
最近浏览
18728748707  LV13 2021年9月7日
ls2008  LV15 2021年7月6日
dashenshi 2020年12月16日
暂无贡献等级
周礼仁  LV2 2020年3月30日
rzl2016  LV10 2019年11月18日
ypt520  LV7 2019年9月11日
半夏秋蚀梦  LV9 2019年7月13日
ColourfulBear 2019年7月4日
暂无贡献等级
xhq1289733981 2019年7月1日
暂无贡献等级
顶部 客服 微信二维码 底部
>扫描二维码关注最代码为好友扫描二维码关注最代码为好友