Spring集成shiro使用redis管理session

接管shiro的缓存只需要重写SessionDAO实现。

spring-shrio.xml相关配置


    
        
        
            
        
    


    
        
        
        
        
        
        
        
    

    
        
        
        
        
    

这里的sessionManager使用的默认的 DefaultWebSessionManager,只重写了sessionDAO实现


ShiroRedisSessionDAO

ShiroRedisSessionDAO.java

package com.sdhs.mob.common.shiro;

import org.apache.commons.collections.CollectionUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.session.mgt.eis.AbstractSessionDAO;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;

import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * shiro redis session
 *
 * @author seer
 * @date 2018/3/25 10:38
 */
public class ShiroRedisSessionDAO extends AbstractSessionDAO {
    private static Logger LOGGER = LogManager.getLogger(ShiroRedisSessionDAO.class);
    /**
     * key前缀
     */
    private static final String SHIRO_REDIS_SESSION_KEY_PREFIX = "shiro.redis.session_";

    private RedisTemplate redisTemplate;

    private ValueOperations valueOperations;

    public ShiroRedisSessionDAO(RedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
        this.valueOperations = redisTemplate.opsForValue();
    }

    @Override
    protected Serializable doCreate(Session session) {
        Serializable sessionId = this.generateSessionId(session);
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("shiro redis session create. sessionId={}", sessionId);
        }
        this.assignSessionId(session, sessionId);
        valueOperations.set(generateKey(sessionId), session, session.getTimeout(), TimeUnit.MILLISECONDS);
        return sessionId;
    }

    @Override
    protected Session doReadSession(Serializable sessionId) {
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("shiro redis session read. sessionId={}", sessionId);
        }
        return (Session) valueOperations.get(generateKey(sessionId));
    }

    @Override
    public void update(Session session) throws UnknownSessionException {
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("shiro redis session update. sessionId={}", session.getId());
        }
        valueOperations.set(generateKey(session.getId()), session, session.getTimeout(), TimeUnit.MILLISECONDS);
    }

    @Override
    public void delete(Session session) {
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("shiro redis session delete. sessionId={}", session.getId());
        }
        redisTemplate.delete(generateKey(session.getId()));
    }

    @Override
    public Collection getActiveSessions() {
        Set keySet = redisTemplate.keys(generateKey("*"));
        Set sessionSet = new HashSet<>();
        if (CollectionUtils.isEmpty(keySet)) {
            return Collections.emptySet();
        }
        for (Object key : keySet) {
            sessionSet.add((Session) valueOperations.get(key));
        }
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("shiro redis session all. size={}", sessionSet.size());
        }
        return sessionSet;
    }

    /**
     * 重组key
     * 区别其他使用环境的key
     *
     * @param key
     * @return
     */
    private String generateKey(Object key) {
        return SHIRO_REDIS_SESSION_KEY_PREFIX + this.getClass().getName() +"_"+ key;
    }
}
 
 

这里使用的redisTemplate操作redis,直接使用redisConnection操作redis可以参考:Spring中使用Redis做为Mybatis二级缓存


直接实现CachingSessionDAO可以最快的实现redis管理session

ShiroRedisCacheSessionDAO.java

package com.sdhs.mob.common.shiro;

import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.eis.CachingSessionDAO;

import java.io.Serializable;

/**
 * ShiroRedisCacheSessionDAO
 *
 * @author seer
 * @date 2018/3/25 16:03
 */
public class ShiroRedisCacheSessionDAO extends CachingSessionDAO {
    @Override
    protected void doUpdate(Session session) {
        this.getCacheManager().getCache(this.getClass().getName()).put(session.getId(), session);
    }

    @Override
    protected void doDelete(Session session) {
        this.getCacheManager().getCache(this.getClass().getName()).remove(session.getId());
    }

    @Override
    protected Serializable doCreate(Session session) {
        Serializable sessionId = this.generateSessionId(session);
        this.assignSessionId(session, sessionId);
        this.getCacheManager().getCache(this.getClass().getName()).put(session.getId(), session);
        return sessionId;

    }

    @Override
    protected Session doReadSession(Serializable sessionId) {
        return (Session) this.getCacheManager().getCache(this.getClass().getName()).get(sessionId);
    }
}

需要配置好cacheManager,参考文档:Spring集成shiro使用redis做缓存


shiro获取session,一次请求多次获取的问题可以参考:shiro 使用redis 频繁请求获取session的问题

你可能感兴趣的:(Spring集成shiro使用redis管理session)