shiro实现基于redis的sessionDao

shiro实现基于redis的sessionDao

将session持久化到数据库的一个关键步骤是对session对象的序列化和反序列化操作,另外在使用redis保存session时一定要设置过期时间,或在编码中检查过期并及时删除缓存,否则会导致session堆积。

具体代码如下:

/**
 * 自定义基于redis的session持久化dao
 * @author ah
 */
public class RedisSessionDao extends CachingSessionDAO {

    private RedisUtil redisUtil;

    public RedisSessionDao(RedisUtil redisUtil) {
        this.redisUtil = redisUtil;
    }

    /**
     * 更新会话;如更新会话最后访问时间/停止会话/设置超时时间/设置移除属性等会调用
     * @param session
     */
    @Override
    protected void doUpdate(Session session) {
        if(session instanceof ValidatingSession && !((ValidatingSession)session).isValid()) {
            return; //如果会话过期/停止 没必要再更新了
        }
        redisUtil.set(RC.key(RC.SEN, Arrays.toString(session.getId().toString().getBytes())), sessionToByte(session));
    }

    /**
     * 删除会话;当会话过期/会话停止(如用户退出时)会调用
     * @param session
     */
    @Override
    protected void doDelete(Session session) {
        redisUtil.del(RC.key(RC.SEN, Arrays.toString(session.getId().toString().getBytes())));
    }

    /**
     * DefaultSessionManager在创建完session后会调用该方法;保存到关系数据库/文件系统/NoSQL数据库;
     * 即可以实现会话的持久化;返回会话ID;主要此处返回的ID.equals(session.getId());
     * @param session
     * @return
     */
    @Override
    protected Serializable doCreate(Session session) {
        Serializable sessionId = generateSessionId(session);
        assignSessionId(session, sessionId);
        redisUtil.set(RC.key(RC.SEN, Arrays.toString(sessionId.toString().getBytes())), sessionToByte(session), session.getTimeout());
        return session.getId();
    }

    /**
     * 根据会话ID获取会话
     * @param serializable
     * @return
     */
    @Override
    protected Session doReadSession(Serializable serializable) {
        Object obj = redisUtil.get(RC.key(RC.SEN, Arrays.toString(serializable.toString().getBytes())));
        if (obj != null) {
            byte[] sessionBytes = (byte[]) redisUtil.get(Arrays.toString(serializable.toString().getBytes()));
            Session session = byteToSession(sessionBytes);
            return session;
        }
        return null;
    }

    // 把session对象转化为byte保存到redis中
    public byte[] sessionToByte(Session session){
        ByteArrayOutputStream bo = new ByteArrayOutputStream();
        byte[] bytes = null;
        try {
            ObjectOutputStream oo = new ObjectOutputStream(bo);
            oo.writeObject(session);
            bytes = bo.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return bytes;
    }

    // 把byte还原为session
    public Session byteToSession(byte[] bytes){
        ByteArrayInputStream bi = new ByteArrayInputStream(bytes);
        ObjectInputStream in;
        SimpleSession session = null;
        try {
            in = new ObjectInputStream(bi);
            session = (SimpleSession) in.readObject();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return session;
    }
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值