Przeglądaj źródła

架构修改前备份

laowo 4 lat temu
rodzic
commit
814b197590

+ 7 - 0
pom.xml

@@ -80,6 +80,13 @@
             <artifactId>shiro-spring</artifactId>
             <version>1.5.2</version>
         </dependency>
+        <dependency>
+            <groupId>org.crazycake</groupId>
+            <artifactId>shiro-redis</artifactId>
+            <version>3.3.1</version>
+        </dependency>
+
+
         <dependency>
             <groupId>org.apache.commons</groupId>
             <artifactId>commons-lang3</artifactId>

+ 21 - 0
src/main/java/com/usky/config/shiro/MyRedisCacheManager.java

@@ -0,0 +1,21 @@
+package com.usky.config.shiro;
+
+import org.apache.shiro.cache.Cache;
+import org.apache.shiro.cache.CacheException;
+import org.apache.shiro.cache.CacheManager;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+
+/**
+ *
+ * @author laowo
+ */
+public class MyRedisCacheManager implements CacheManager {
+    @Autowired
+    private RedisTemplate redisTemplate;
+
+    @Override
+    public <K, V> Cache<K, V> getCache(String name) throws CacheException {
+        return new ShiroRedisCache(name,redisTemplate);
+    }
+}

+ 224 - 0
src/main/java/com/usky/config/shiro/ShiroRedisCache.java

@@ -0,0 +1,224 @@
+package com.usky.config.shiro;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.shiro.cache.Cache;
+import org.apache.shiro.cache.CacheException;
+import org.springframework.data.redis.connection.RedisConnection;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
+import org.springframework.data.redis.serializer.RedisSerializer;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ *
+ */
+public class ShiroRedisCache<K, V> implements Cache<K, V> {
+    private static Logger LOGGER = LogManager.getLogger(ShiroRedisCache.class);
+
+    /**
+     * key前缀
+     */
+    private static final String REDIS_SHIRO_CACHE_KEY_PREFIX = "shiro_cache_key_";
+
+    /**
+     * cache name
+     */
+    private String name;
+
+    /**
+     * jedis 连接工厂
+     */
+
+    private RedisTemplate redisTemplate;
+
+    /**
+     * 序列化工具
+     */
+    private RedisSerializer serializer = new JdkSerializationRedisSerializer();
+
+    /**
+     * 存储key的redis.list的key值
+     */
+    private String keyListKey;
+
+    private RedisConnection getConnection(){
+        return this.redisTemplate.getConnectionFactory().getConnection();
+    }
+
+    public ShiroRedisCache(String name,RedisTemplate redisTemplate) {
+        this.name = name;
+        this.redisTemplate = redisTemplate;
+        this.keyListKey = REDIS_SHIRO_CACHE_KEY_PREFIX + name;
+    }
+
+    @Override
+    public V get(K key) throws CacheException {
+        LOGGER.debug("shiro redis cache get.{} K={}", name, key);
+        RedisConnection redisConnection = null;
+        V result = null;
+        try {
+            redisConnection = getConnection();
+            result = (V) serializer.deserialize(redisConnection.get(serializer.serialize(generateKey(key))));
+        } catch (Exception e) {
+            LOGGER.error("shiro redis cache get exception. ", e);
+        } finally {
+            if (null != redisConnection) {
+                redisConnection.close();
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public V put(K key, V value) throws CacheException {
+        LOGGER.debug("shiro redis cache put.{} K={} V={}", name, key, value);
+        RedisConnection redisConnection = null;
+        V result = null;
+        try {
+            redisConnection = getConnection();
+            result = (V) serializer.deserialize(redisConnection.get(serializer.serialize(generateKey(key))));
+
+            redisConnection.set(serializer.serialize(generateKey(key)), serializer.serialize(value));
+
+            redisConnection.lPush(serializer.serialize(keyListKey), serializer.serialize(generateKey(key)));
+        } catch (Exception e) {
+            LOGGER.error("shiro redis cache put exception. ", e);
+        } finally {
+            if (null != redisConnection) {
+                redisConnection.close();
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public V remove(K key) throws CacheException {
+        LOGGER.debug("shiro redis cache remove.{} K={}", name, key);
+        RedisConnection redisConnection = null;
+        V result = null;
+        try {
+            redisConnection = getConnection();
+            result = (V) serializer.deserialize(redisConnection.get(serializer.serialize(generateKey(key))));
+
+            redisConnection.expireAt(serializer.serialize(generateKey(key)), 0);
+
+            redisConnection.lRem(serializer.serialize(keyListKey), 1, serializer.serialize(key));
+        } catch (Exception e) {
+            LOGGER.error("shiro redis cache remove exception. ", e);
+        } finally {
+            if (null != redisConnection) {
+                redisConnection.close();
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public void clear() throws CacheException {
+        LOGGER.debug("shiro redis cache clear.{}", name);
+        RedisConnection redisConnection = null;
+        try {
+            redisConnection = getConnection();
+
+            Long length = redisConnection.lLen(serializer.serialize(keyListKey));
+            if (0 == length) {
+                return;
+            }
+
+            List<byte[]> keyList = redisConnection.lRange(serializer.serialize(keyListKey), 0, length - 1);
+            for (byte[] key : keyList) {
+                redisConnection.expireAt(key, 0);
+            }
+
+            redisConnection.expireAt(serializer.serialize(keyListKey), 0);
+            keyList.clear();
+        } catch (Exception e) {
+            LOGGER.error("shiro redis cache clear exception.", e);
+        } finally {
+            if (null != redisConnection) {
+                redisConnection.close();
+            }
+        }
+    }
+
+    @Override
+    public int size() {
+        LOGGER.debug("shiro redis cache size.{}", name);
+        RedisConnection redisConnection = null;
+        int length = 0;
+        try {
+            redisConnection = getConnection();
+            length = Math.toIntExact(redisConnection.lLen(serializer.serialize(keyListKey)));
+        } catch (Exception e) {
+            LOGGER.error("shiro redis cache size exception.", e);
+        } finally {
+            if (null != redisConnection) {
+                redisConnection.close();
+            }
+        }
+        return length;
+    }
+
+    @Override
+    public Set keys() {
+        LOGGER.debug("shiro redis cache keys.{}", name);
+        RedisConnection redisConnection = null;
+        Set resultSet = null;
+        try {
+            redisConnection = getConnection();
+
+            Long length = redisConnection.lLen(serializer.serialize(keyListKey));
+            if (0 == length) {
+                return resultSet;
+            }
+
+            List<byte[]> keyList = redisConnection.lRange(serializer.serialize(keyListKey), 0, length - 1);
+            resultSet = keyList.stream().map(bytes -> serializer.deserialize(bytes)).collect(Collectors.toSet());
+        } catch (Exception e) {
+            LOGGER.error("shiro redis cache keys exception.", e);
+        } finally {
+            if (null != redisConnection) {
+                redisConnection.close();
+            }
+        }
+        return resultSet;
+    }
+
+    @Override
+    public Collection values() {
+        RedisConnection redisConnection = getConnection();
+        Set keys = this.keys();
+
+        List<Object> values = new ArrayList<Object>();
+        for (Object key : keys) {
+            byte[] bytes = redisConnection.get(serializer.serialize(key));
+            values.add(serializer.deserialize(bytes));
+        }
+        return values;
+    }
+
+    /**
+     * 重组key
+     * 区别其他使用环境的key
+     *
+     * @param key
+     * @return
+     */
+    private String generateKey(K key) {
+        return REDIS_SHIRO_CACHE_KEY_PREFIX + name + "_" + key;
+    }
+
+    private byte[] getByteKey(K key) {
+        if (key instanceof String) {
+            String preKey = generateKey(key);
+            return preKey.getBytes();
+        }
+        return serializer.serialize(key);
+    }
+}

+ 72 - 0
src/main/java/com/usky/config/shiro/ShiroRedisSessionDao.java

@@ -0,0 +1,72 @@
+package com.usky.config.shiro;
+
+import org.apache.shiro.session.Session;
+import org.apache.shiro.session.mgt.eis.CachingSessionDAO;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+
+import java.io.Serializable;
+
+/**
+ *
+ */
+public class ShiroRedisSessionDao extends CachingSessionDAO {
+
+    public static final String SHIRO_SESSION_KEY = "shiro_session_key";
+
+    private Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    @Autowired
+    private RedisTemplate redisTemplate; //spring-data-redis
+
+    @Override
+    protected void doUpdate(Session session) {
+        this.saveSession(session);
+    }
+
+    @Override
+    protected void doDelete(Session session) {
+        if (session == null || session.getId() == null) {
+            logger.error("session or session id is null");
+            return;
+        }
+        //根据session id删除session
+        redisTemplate.boundHashOps(SHIRO_SESSION_KEY).delete(session.getId());
+    }
+
+
+    @Override
+    protected Serializable doCreate(Session session) {
+        Serializable sessionId = this.generateSessionId(session);
+        this.assignSessionId(session, sessionId);
+        this.saveSession(session);
+        return sessionId;
+    }
+
+
+    @Override
+    protected Session doReadSession(Serializable sessionId) {
+        if (sessionId == null) {
+            logger.error("传入的 session id is null");
+            return null;
+        }
+        Object o = redisTemplate.boundHashOps(SHIRO_SESSION_KEY).get(sessionId);
+
+        return (Session) o;
+    }
+
+    /**
+     * 将session 保存进redis 中
+     *
+     * @param session 要保存的session
+     */
+    private void saveSession(Session session) {
+        if (session == null || session.getId() == null) {
+            logger.error("session or session id is null");
+            return;
+        }
+        redisTemplate.boundHashOps(SHIRO_SESSION_KEY).put(session.getId(), session);
+    }
+}